const router = require('express').Router();
const { body } = require('express-validator');

const {
  createListing,
  createListingAddOns,
  deleteListingAddOns,
  getLastListingInfo,
  updateListing,
  updateListingAddOns,
} = require('../../../controllers/host/v1.1/listings');
const { deleteFile, jsonParser } = require('../../../helpers');
const { isAuth, validation } = require('../../../middlewares');

router.post(
  '/',
  jsonParser,
  [
    body('data.listingName').notEmpty(),
    body('data.description').notEmpty(),
    body('data.fullname').isString().optional(),
    body('data.businessName').isString().optional(),
    body('data.businessAddress').isString().optional(),
    body('data.listingType').isIn(['Public', 'Private']),
    body('data.location').isString(),
    body('data.latitude').notEmpty(),
    body('data.longitude').notEmpty(),
    body('data.extraGuestFee').isDecimal().optional({
      values: 'falsy',
    }),
    body('data.tents').isNumeric().optional(),
    body('data.vans').isNumeric().optional(),
    body('data.cleaningFee').isDecimal(),
    body('data.smokingPolicy').optional({ values: 'falsy' }),
    body('data.petsPolicy').optional({ values: 'falsy' }),
    body('data.quietHoursStart').isString(),
    body('data.quietHoursEnd').isString(),
    body('data.securityDeposit').isBoolean(),
    body('data.securityDepositPrice').custom((value, { req }) => {
      const { securityDeposit, securityDepositPrice } = req.body.data;
      if (securityDeposit === true || securityDeposit === 'true') {
        if (
          securityDepositPrice === undefined ||
          securityDepositPrice === null ||
          securityDepositPrice === '' ||
          isNaN(Number(securityDepositPrice))
        ) {
          throw new Error('securityDepositPrice is required when securityDeposit is true.');
        }
      }
      return true;
    }),
    body('data.approval').isIn(['Auto', 'Manual']),
    body('data.addressCountry').notEmpty(),
    body('data.addressStreet').notEmpty(),
    body('data.addressApt').isString().optional(),
    body('data.addressCity').notEmpty(),
    body('data.addressState').notEmpty(),
    body('data.addressZip').notEmpty(),
    body('data.paymentMethod')
      .optional()
      .custom((value, { req }) => {
        const { paymentMethod } = req.body.data;

        for (const field of ['bankName', 'bankAccountName', 'bankAccountNumber']) {
          if (!paymentMethod[field]) {
            throw new Error(`${field} is required for Debit/Credit payment method.`);
          }
        }

        return true;
      }),
    body().custom((value, { req }) => {
      const files = req.files || {};
      const listingImgs = files.listingImgs || [];

      const { data } = req.body;

      const listingImageCategories = data?.listingImageCategories ?? [];

      if (listingImgs?.length === 0) {
        throw new Error('Listing images are required.');
      }
      if (listingImageCategories.length !== listingImgs.length) {
        throw new Error(
          'Listing image categories are required and should match the number of files.',
        );
      }

      if (data.listingType === 'Public') {
        if (!data?.spots || data?.spots?.length === 0 || !Array.isArray(data.spots)) {
          throw new Error('Missing or invalid required field: listing spots');
        }
      }

      return true;
    }),
    body().custom((value, { req }) => {
      const jsonFields = [
        'amenities',
        'services',
        'listingImageCategories',
        'addOns',
        'discounts',
        'spots',
      ];

      const { data } = req.body;

      for (const field of jsonFields) {
        if (data[field]) {
          try {
            if (!Array.isArray(data[field])) {
              throw new Error(`${field} must be an array.`);
            }
          } catch (error) {
            throw new Error(`${field} must be a valid JSON array.`);
          }
        }
      }
      return true;
    }),
    body().custom((value, { req }) => {
      const files = req.files || {};
      const supportingDocs = files.supportingDocs || [];

      const { data } = req.body;

      if (data.useLastInfo) {
        if (supportingDocs.length > 0) {
          for (const file of supportingDocs) {
            deleteFile(file.filename, 'host-uploads');
          }
        }

        return true;
      }

      const supportingDocTypes = data?.supportingDocTypes ?? [];

      // if (!supportingDocTypes || supportingDocTypes.length === 0) {
      // 	throw new Error('Supporting document types are required.');
      // }

      if (supportingDocTypes.length !== supportingDocs.length) {
        throw new Error(
          'Supporting document types are required and should match the number of files.',
        );
      }

      const { hostingType } = data;

      if (!hostingType) {
        throw new Error('Hosting type is required.');
      }

      const requiredFiles = {
        Individual: {
          // files: ['Proof of Ownership/Lease'],
          fields: ['fullname', 'birthDate', 'birthPlace'],
        },
        Business: {
          // files: [
          // 	'Business Permit',
          // 	'DTI/SEC Registration',
          // 	'Bureau of Internal Revenue', //?same
          // 	'BIR Certificate of Registration', //?same
          // ],
          fields: ['businessName', 'businessAddress', 'businessType'],
        },
        // Corporation: {
        // 	files: ['SEC Certificate of Incorporation', 'Articles of Incorporation', 'Company Profile'],
        // },
      };

      for (const key in requiredFiles) {
        if (hostingType === key) {
          const {
            // files: requiredDocs,
            fields: requiredFields = [],
          } = requiredFiles[key];

          // Use if you want to check the number of files uploaded

          // if (key === 'Individual') {
          // 	if (supportingDocTypes.length < 2) {
          // 		throw new Error('Missing required documents for Individual hosting type.');
          // 	}
          // }
          // for (const doc of requiredDocs) {
          // 	if (!supportingDocTypes.includes(doc)) {
          // 		throw new Error(`Missing required document: ${doc}`);
          // 	}
          // }

          for (const field of requiredFields) {
            if (!data[field] || data[field].trim() === '') {
              throw new Error(`Missing required field: ${field}`);
            }
          }
        }
      }

      return true;
    }),
    validation,
  ],
  isAuth,
  createListing,
);

router.post(
  '/add-ons/:listingId',
  isAuth,
  [
    body('addOns.*.addOnName').notEmpty().withMessage('Add-on name is required for each item'),
    body('addOns.*.price').notEmpty().withMessage('Price is required for each item'),
    // body('addOns.*.category').notEmpty().withMessage('Category is required for each item'),
    validation,
  ],
  createListingAddOns,
);

router.patch(
  '/add-ons/:listingAddOnId',
  isAuth,
  [
    body('addOnName').notEmpty().optional(),
    body('price').notEmpty().optional(),
    body('category').notEmpty().optional(),
    validation,
  ],
  updateListingAddOns,
);

router.patch(
  '/:listingId',
  isAuth,
  jsonParser,
  [
    body('data.name').optional(),
    body('data.description').optional(),
    body('data.hostingType').optional().isIn(['Individual', 'Business', 'Corporation']),
    body('data.fullname').optional().isString(),
    body('data.businessName').optional().isString(),
    body('data.businessAddress').optional().isString(),
    body('data.listingType').optional().isIn(['Public', 'Private']),
    body('data.location').optional().isString(),
    body('data.latitude').optional(),
    body('data.longitude').optional(),
    body('data.tents').isNumeric().optional(),
    body('data.vans').isNumeric().optional(),
    body('data.extraGuestFee')
      .optional({
        values: 'falsy',
      })
      .isDecimal(),
    body('data.cleaningFee').optional().isDecimal(),
    body('data.cancellationPolicy')
      .optional()
      .isIn([
        'Flexible (Full refund 24 hours before check-in)',
        'Moderate (50% refund 3 days before check-in)',
        'Strict (No refund 7 days before check-in)',
      ]),
    body('data.smokingPolicy').optional({
      values: 'falsy',
    }),
    body('data.petsPolicy').optional({
      values: 'falsy',
    }),
    body('data.quietHoursStart').optional().isString(),
    body('data.quietHoursEnd').optional().isString(),
    body('data.securityDeposit').optional().isBoolean(),
    body('data.securityDepositPrice').optional().isDecimal(),
    body('data.approval').optional().isIn(['Auto', 'Manual']),
    body('data.paymentMethod')
      .optional()
      .custom((value, { req }) => {
        if (value && typeof value !== 'object') {
          throw new Error('paymentMethod must be an object.');
        }
        return true;
      }),
    validation,
  ],
  updateListing,
);

router.put(
  '/:listingId',
  isAuth,
  jsonParser,
  [
    body('data.name').optional(),
    body('data.description').optional(),
    body('data.hostingType').optional().isIn(['Individual', 'Business', 'Corporation']),
    body('data.fullname').optional().isString(),
    body('data.businessName').optional().isString(),
    body('data.businessAddress').optional().isString(),
    body('data.listingType').optional().isIn(['Public', 'Private']),
    body('data.location').optional().isString(),
    body('data.latitude').optional(),
    body('data.longitude').optional(),
    body('data.tents').isNumeric().optional(),
    body('data.vans').isNumeric().optional(),
    body('data.extraGuestFee')
      .optional({
        values: 'falsy',
      })
      .isDecimal(),
    body('data.cleaningFee').optional().isDecimal(),
    body('data.cancellationPolicy')
      .optional()
      .isIn([
        'Flexible (Full refund 24 hours before check-in)',
        'Moderate (50% refund 3 days before check-in)',
        'Strict (No refund 7 days before check-in)',
      ]),
    body('data.smokingPolicy').optional({
      values: 'falsy',
    }),
    body('data.petsPolicy').optional({
      values: 'falsy',
    }),
    body('data.quietHoursStart').optional().isString(),
    body('data.quietHoursEnd').optional().isString(),
    body('data.securityDeposit').optional().isBoolean(),
    body('data.securityDepositPrice').optional().isDecimal(),
    body('data.approval').optional().isIn(['Auto', 'Manual']),
    body('data.paymentMethod')
      .optional()
      .custom((value, { req }) => {
        if (value && typeof value !== 'object') {
          throw new Error('paymentMethod must be an object.');
        }
        return true;
      }),
    validation,
  ],
  updateListing,
);

router.delete('/add-ons/:listingAddOnId', isAuth, deleteListingAddOns);

router.get('/last-info', isAuth, getLastListingInfo);

module.exports = router;
