const { PaymentMethods } = require('../../../models');
const { formatCase, formatCaseDeep } = require('../../../util/formatter');

function formatPaymentMethods(data) {
  if (Array.isArray(data)) {
    return data.map(formatPaymentMethods);
  }
  if (data.type) {
    switch (data.type) {
      case 'Debit/Credit':
        return {
          id: data.id,
          type: data.type,
          card_number: data.card_number,
          expiration: data.expiration,
          cvv: data.cvv,
          name_of_card: data.name_of_card,
          name: data.name,
          phone: data.phone,
          email: data.email,
        };
      case 'Paypal':
        return {
          id: data.id,
          type: data.type,
          email: data.email,
          name: data.name,
        };
      case 'Gcash':
        return {
          id: data.id,
          type: data.type,
          name: data.name,
          phone: data.phone,
        };
      default:
        return data;
    }
  }
  return data;
}

exports.createPaymentMethod = async (req, res, next) => {
  try {
    const { userId } = req;

    const { type } = req.body;

    if (!type) {
      return res.status(400).json({
        success: false,
        message: 'Payment method type is required',
      });
    }

    switch (type) {
      case 'Debit/Credit':
        if (
          !req.body.cardNumber ||
          !req.body.expiration ||
          !req.body.cvv ||
          !req.body.nameOfCard ||
          !req.body.name ||
          !req.body.phone ||
          !req.body.email
        ) {
          return res.status(400).json({
            success: false,
            message: 'Missing required fields for Debit/Credit payment method',
          });
        }
        break;
      case 'Paypal':
        if (!req.body.email || !req.body.name) {
          return res.status(400).json({
            success: false,
            message: 'Missing required fields for Paypal payment method',
          });
        }
        break;
      case 'Gcash':
        if (!req.body.name || !req.body.phone) {
          return res.status(400).json({
            success: false,
            message: 'Missing required fields for Gcash payment method',
          });
        }
        break;
      default:
        return res.status(400).json({
          success: false,
          message: 'Invalid payment method type',
        });
    }

    const data = formatCase(req.body, 'snake');

    const paymentMethod = await PaymentMethods.create({
      customer_id: userId,
      ...data,
    });

    return res.status(201).json({
      success: true,
      message: 'Payment method created successfully',
      data: paymentMethod,
    });
  } catch (error) {
    next(error);
  }
};

exports.getPaymentMethods = async (req, res, next) => {
  try {
    const { userId } = req;
    const { type } = req.query;
    const paymentMethods = await PaymentMethods.findAll({
      attributes: {
        exclude: ['customer_id'],
      },
      where: {
        customer_id: userId,
        ...(type ? { type } : {}),
      },
    });

    return res.status(200).json({
      success: true,
      data: paymentMethods ? formatCaseDeep(formatPaymentMethods(paymentMethods)) : null,
    });
  } catch (error) {
    next(error);
  }
};

exports.updatePaymentMethod = async (req, res, next) => {
  try {
    const { id } = req.params;
    const data = formatCase(req.body, 'snake');

    const paymentMethod = await PaymentMethods.findOne({
      where: {
        id: id,
      },
    });

    if (!paymentMethod) {
      return res.status(404).json({
        success: false,
        message: 'Payment method not found',
      });
    }

    await paymentMethod.update(data);

    return res.status(200).json({
      success: true,
      message: 'Payment method updated successfully',
      data: paymentMethod,
    });
  } catch (error) {
    next(error);
  }
};

exports.deletePaymentMethod = async (req, res, next) => {
  try {
    const { id } = req.params;

    const paymentMethod = await PaymentMethods.findOne({
      where: {
        id: id,
      },
    });

    if (!paymentMethod) {
      return res.status(404).json({
        success: false,
        message: 'Payment method not found',
      });
    }

    await paymentMethod.destroy();

    return res.status(200).json({
      success: true,
      message: 'Payment method deleted successfully',
    });
  } catch (error) {
    next(error);
  }
};
