"use strict";
const settingsModel = require("../models/settingModel");
const SettingsModel = new settingsModel();
const hostModel = require("../models/hostModel");
const Host = new hostModel();
const twilioHelper = require("../helpers/twilioHelper");
const TwilioHelper = new twilioHelper();
const utility = require("../helpers/utility");
const Utility = new utility();
const Response = require("../helpers/responseHelper");
const OTPService = require("../services/otpService");

class HostsController {
  async hostCalculatorSettings(req, res) {
    try {
      const results = await SettingsModel.hostCalculatorSettings();
      if (results.length === 0) {
        return Response.error(res, "NOT_FOUND", "No settings found", 404);
      }

      var settingCategories = results.flatMap((setting) => setting.category);
      settingCategories = settingCategories.filter(function (item, pos) {
        return settingCategories.indexOf(item) == pos;
      });
      var hostSettings = {};
      settingCategories.forEach((category) => {
        var settings = results.filter((result) => result.category == category);
        var arr = [];
        settings.forEach((setting) => {
          arr.push({ id: setting.id, name: setting.name });
        });
        hostSettings[category] = arr;
      });

      return Response.success(res, hostSettings);
    } catch (err) {
      return Response.error(res, "FETCH_FAILED", "Settings not found", 400);
    }
  }

  async generateOTP(req, res) {
    try {
      const { phone, email } = req.body;
      if (!phone && !email) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "Phone number or email missing or invalid!",
          400,
        );
      }

      const { otp, expires_at } = OTPService.generateOTP(OTPService.getExpiryTime('host'));

      var body = "Your staymaster OTP is: " + otp;

      if (phone) {
        await Host.saveOTP(phone, otp, expires_at);
        try {
          // Handle phone number format - if it starts with a number, add +
          const formattedPhone = phone.startsWith("+") ? phone : `+${phone}`;
          await TwilioHelper.sendSMS(body, "+12163036560", formattedPhone);
          console.log(`OTP sent to ${formattedPhone}`);
        } catch (smsError) {
          console.error("SMS sending error:", smsError);
          // Continue execution even if SMS fails
        }
      }

      if (email) {
        // For email OTP
        await Host.saveOTP(null, otp, expires_at, email);
        try {
          await Utility.sendEMail(email, "OTP from StayMaster", body);
          console.log(`OTP sent to email ${email}`);
        } catch (emailError) {
          console.error("Email sending error:", emailError);
          // Continue execution even if email fails
        }
      }

      // Return the OTP for testing purposes
      return Response.success(res, { otp });
    } catch (error) {
      console.error("OTP generation error:", error);
      return Response.error(
        res,
        "OTP_GENERATION_FAILED",
        "OTP could not be sent. Please try again.",
        400,
      );
    }
  }

  async hostEnquiry(req, res) {
    try {
      const {
        location,
        property_type,
        bedrooms,
        pool_type,
        name,
        email,
        phone,
        otp,
      } = req.body;
      if (
        !location ||
        !property_type ||
        !bedrooms ||
        !pool_type ||
        !name ||
        !email ||
        !otp ||
        (!phone && !email)
      ) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "One or more mandatory parameters missing!",
          400,
        );
      }

      // Test OTP bypass (only in development with env var)
      if (OTPService.isTestOTPAllowed() && OTPService.isTestOTP(otp)) {
        // For bypass OTP, we'll allow creating a new host record if needed
        let hostRecord;

        if (phone) {
          hostRecord = await Host.findByPhone(phone);
          // If not found, create a new host entry
          if (!hostRecord) {
            console.log(`Creating new host entry with phone: ${phone}`);
            await Host.saveOTP(
              phone,
              otp,
              Math.round(Date.now() / 1000) + 3600,
            );
            hostRecord = await Host.findByPhone(phone);
          }
        } else if (email) {
          hostRecord = await Host.findByEmail(email);
          // If not found, create a new host entry
          if (!hostRecord) {
            console.log(`Creating new host entry with email: ${email}`);
            await Host.saveOTP(
              null,
              otp,
              Math.round(Date.now() / 1000) + 3600,
              email,
            );
            hostRecord = await Host.findByEmail(email);
          }
        }

        if (!hostRecord) {
          return Response.error(
            res,
            "CREATE_FAILED",
            "Failed to create host record!",
            400,
          );
        }

        await Host.saveHostDetails(
          hostRecord[0].id,
          location,
          property_type,
          bedrooms,
          pool_type,
          name,
          email,
        );

        const results = await SettingsModel.hostSettingsByParams(
          location,
          property_type,
          bedrooms,
          pool_type,
        );
        var base_rental = 5000 * 91.25;
        var location_record;
        results.forEach((result) => {
          base_rental = base_rental * result.multiplier;
          if (result.setting_id == location) {
            location_record = result;
          }
        });
        var rentals = {};
        const months = [
          "january",
          "february",
          "march",
          "april",
          "may",
          "june",
          "july",
          "august",
          "september",
          "october",
          "november",
          "december",
        ];
        months.forEach((month) => {
          rentals[month] = base_rental * location_record[month];
        });
        base_rental = Math.round(base_rental);
        return Response.success(res, { rentals, base_rental });
      }

      // Regular OTP verification
      let userAvailable;
      if (phone) {
        userAvailable = await Host.hostExists(phone, otp);
      } else if (email) {
        userAvailable = await Host.hostExistsByEmail(email, otp);
      }

      if (!userAvailable) {
        return Response.error(
          res,
          "OTP_INVALID",
          "Contact information not found or OTP invalid!",
          400,
        );
      }

      const currentTime = Math.round(Date.now() / 1000);
      if (currentTime >= userAvailable.expires_at) {
        return Response.error(
          res,
          "OTP_EXPIRED",
          "OTP invalid or expired!",
          400,
        );
      }

      await Host.saveHostDetails(
        userAvailable[0].id,
        location,
        property_type,
        bedrooms,
        pool_type,
        name,
        email,
      );
      const results = await SettingsModel.hostSettingsByParams(
        location,
        property_type,
        bedrooms,
        pool_type,
      );
      var base_rental = 5000 * 91.25;
      var location_record;
      results.forEach((result) => {
        base_rental = base_rental * result.multiplier;
        if (result.setting_id == location) {
          location_record = result;
        }
      });
      var rentals = {};
      const months = [
        "january",
        "february",
        "march",
        "april",
        "may",
        "june",
        "july",
        "august",
        "september",
        "october",
        "november",
        "december",
      ];
      months.forEach((month) => {
        rentals[month] = base_rental * location_record[month];
      });
      base_rental = Math.round(base_rental);
      return Response.success(res, { rentals, base_rental });
    } catch (error) {
      return Response.error(res, "FETCH_FAILED", "Issue with fetching", 400);
    }
  }

  async hostsByProperty(req, res) {
    const { propertyId } = req.params;
    const hosts = await Host.hostsByProperty(propertyId);
    return Response.success(res, { hosts });
  }
}
module.exports = HostsController;
