const user = require("../models/userModel");
const User = new user();
const smModel = require("../models/smModel");
const SMModel = new smModel();
const property = require("../models/propertyModel");
const Property = new property();
const settingModel = require("../models/settingModel");
const Setting = new settingModel();
const settingsHelper = require("../helpers/settingsHelper");
const SettingsHelper = new settingsHelper();
const twilioHelper = require("../helpers/twilioHelper");
const TwilioHelper = new twilioHelper();
const QueryCondition = require("../helpers/utilsHelper");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const Response = require("../helpers/responseHelper");

const bucket = process.env.AWS_COLLECTION_BUCKET;
const { format, addDays, differenceInDays } = require("date-fns");
const userFields = [
  "firstname",
  "lastname",
  "email",
  "phone",
  "add",
  "gender",
  "address_line_1",
  "address_line_2",
  "city",
  "state",
  "country",
  "postcode",
];
const hostFields = [
  "firstname",
  "lastname",
  "email",
  "phone",
  "gender",
  "address_line_1",
  "address_line_2",
  "city",
  "state",
  "country",
  "postcode",
  "date_of_birth",
  "date_of_joining",
];
const userTypes = { 270: "staff", 267: "host" };
const userRoles = { staff: 270, host: 267 };
const constants = require("../config/constants");
const utility = require("../helpers/utility");
const Utility = new utility;
const OTPService = require("../services/otpService");
const AuthService = require("../services/AuthService");

class UsersController {
  async me(req, res) {
    try {
      if (req.user) {
        const me = await User.getById(req.user.id);
        Response.success(res, me[0]);
      }
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to fetch user", 500);
    }
  }

  async checkUnique(req, res) {
    try {
      const conditions = [];
      const { type, value, userType, currentId } = req.params;
      conditions.push(new QueryCondition("role", "=", userRoles[userType]));
      conditions.push(new QueryCondition(type, "=", value));
      if (currentId) {
        conditions.push(new QueryCondition("id", "<>", currentId));
      }
      var result = await SMModel.exists("users", conditions);
      Response.success(res, { exists: result });
    } catch (error) {
      console.log(error);
    }
  }

  async generateUserOTP(req, res) {
    try {
      const { email } = req.body;

      if (!email) {
        return res.status(200).json({
          success: false,
          message: "Email is mandatory",
        });
      }

      await otpService.generateUserOTPservice(email);

      Response.success(res, {
        message: `OTP sent via email to ${email}`,
      });
    } catch (error) {
      Response.error(
        res,
        "OTP_FAILED",
        error?.message || "Please try after some time",
        400,
      );
    }
  }

  async generateGuestOTP(req, res) {
    try {
      const { phone } = req.body;

      if (!phone) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "Phone number missing or invalid!",
          400,
        );
      }

      const { otp } = await otpService.generateGuestOTPservice(phone);

      Response.success(res, { otp });
    } catch (error) {
      Response.error(
        res,
        "OTP_FAILED",
        error?.message || "Please try after some time",
        400,
      );
    }
  }

  async generateHostOTP(req, res) {
    try {
      const { phone, email } = req.body;

      if (!phone && !email) {
        return res.status(400).json({
          success: false,
          message: "Phone number or email missing or invalid!",
        });
      }

      const { otp } = await otpService.generateHostOTPservice({ phone, email });

      Response.success(res, { otp });
    } catch (error) {
      console.error("OTP generation error:", error);

      Response.error(
        res,
        "OTP_FAILED",
        error?.message || "Please try after some time",
        400,
      );
    }
  }

  async loginUser(req, res) {
    try {
      const { email, password } = req.body;

      if (!email || !password) {
        return res.status(200).json({
          success: false,
          message: "Email and password are mandatory",
        });
      }

      const result = await AuthService.loginUserService(email, password);

      if (!result.success) {
        return res.render("login.ejs", { flash: result.message });
      }
      res.cookie("authcookie", result.accessToken, {
        maxAge: 9000000,
        httpOnly: true,
      });

      return res.redirect("/admin/");
    } catch (error) {
      console.error("loginUser error:", error);
      return res.render("login.ejs", {
        flash: "Something went wrong. Please try again.",
      });
    }
  }

  async loginWithEmail(email, password, role) {
    if (!email || !password) {
      return { success: false, error: "Email and password are mandatory" };
    }
    const userAvailable = await User.find("users", {
      email: email,
      role: role,
    });
    if (
      userAvailable &&
      userAvailable.role == role &&
      (await bcrypt.compare(password, userAvailable.password))
    ) {
      const accessToken = jwt.sign(
        {
          user: {
            email: userAvailable.email,
            id: userAvailable.id,
          },
        },
        process.env.ACCESS_TOKEN_SECRET,
        { expiresIn: "300m" },
      );
      const u = userAvailable;
      const user = {
        id: u.id,
        firstname: u.firstname,
        lastname: u.lastname,
        email: u.email,
        phone: u.phone,
      };
      return { success: true, accessToken, user };
    }
    return { success: false, error: "Invalid credentials" };
  }

  async guestLoginWithOTP(req, res) {
    try {
      const { phone, otp } = req.body;

      const result = await AuthService.guestLoginWithOTPService(phone, otp);

      if (!result.success) {
        return res.status(400).json({ success: false, message: result.error });
      }

      // HTTP concern controller me hi
      res.cookie("logincookie", result.accessToken, {
        maxAge: 9000000,
        httpOnly: true,
      });

      Response.success(res, {
        webUserToken: result.accessToken,
        user: result.user,
      });
    } catch (error) {
      console.error("guestLoginWithOTP error:", error);
      Response.error(res, "AUTH_FAILED", "Login failed", 400);
    }
  }

  async hostLogin(req, res) {
    try {
      const { phone, otp, email, password } = req.body;

      if (!phone && !otp && !email && !password) {
        return res.status(400).json({
          success: false,
          message: "Phone and OTP or Email and Password are mandatory",
        });
      }

      const result = await AuthService.hostLoginService({
        phone,
        otp,
        email,
        password,
      });

      if (!result.success) {
        return res.status(400).json({ success: false, message: result.error });
      }

      // HTTP concern
      res.cookie("logincookie", result.accessToken, {
        maxAge: 9000000,
        httpOnly: true,
      });

      Response.success(res, {
        webUserToken: result.accessToken,
        user: result.user,
      });
    } catch (error) {
      console.error("hostLogin error:", error);
      Response.error(res, "AUTH_FAILED", result.error, 400);
    }
  }

  async loginWithOTP(phone, otp, role) {
    if (!phone || !otp) {
      return { success: false, error: "Phone and OTP are mandatory" };
    }

    const userAvailable = await User.find("users", {
      phone: phone,
      role: role,
    });
    if (!userAvailable) {
      return { success: false, error: "Unrecognised Phone number" };
    }

    // Test OTP bypass (only in development with env var)
    if (OTPService.isTestOTPAllowed() && OTPService.isTestOTP(otp)) {
      const accessToken = jwt.sign(
        {
          user: {
            email: userAvailable.phone,
            id: userAvailable.id,
            transExpiry: Math.round(Date.now() / 1000) + 60 * 60,
          },
        },
        process.env.ACCESS_TOKEN_SECRET,
        { expiresIn: "60m" },
      );
      const u = userAvailable;
      const user = {
        id: u.id,
        firstname: u.firstname,
        lastname: u.lastname,
        email: u.email,
        phone: u.phone,
      };
      return { success: true, accessToken, user };
    }

    // Regular OTP verification
    const currentTime = Math.round(Date.now() / 1000);
    const result = await User.find("otp", {
      user_id: userAvailable.id,
      otp: otp,
    });
    if (!result || result.length == 0 || currentTime >= result.expires_at) {
      return { success: false, error: "OTP invalid or expired" };
    }
    const accessToken = jwt.sign(
      {
        user: {
          email: userAvailable.phone,
          id: userAvailable.id,
          transExpiry: Math.round(Date.now() / 1000) + 60 * 60, //60 minutes expiry
        },
      },
      process.env.ACCESS_TOKEN_SECRET,
      { expiresIn: "60m" },
    );
    const u = userAvailable;
    const user = {
      id: u.id,
      firstname: u.firstname,
      lastname: u.lastname,
      email: u.email,
      phone: u.phone,
    };
    return { success: true, accessToken, user };
  }

  async changePassword(req, res) {
    try {
      var { id } = req.params;
      var own = 0;
      if (!id || id == req.user.id) {
        id = req.user.id;
        own = 1;
      }
      const user = await User.getById(id);
      await res.render("users/changePassword.ejs", { own, user: user[0] });
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async savePassword(req, res) {
    try {
      const { id, current_password, new_password, confirm_password } = req.body;
      var user = await User.getById(id);
      if (id == req.user.id) {
        if (
          !current_password ||
          !(await bcrypt.compare(current_password, user[0].password))
        ) {
          Response.error(res, "INVALID_PASSWORD", "Current password incorrect");
          return;
        }
      }
      if (new_password == confirm_password) {
        user[0].password = await bcrypt.hash(new_password, 10);
        await SMModel.updateTableEntry("users", user[0], id);
      } else {
        res.status(200).json({
          success: false,
          cause: "new password and confirm password do not match",
        });
        return;
      }
      const flash = `Password changed successfully for ${user[0].firstname} ${user[0].lastname}`;
      Response.success(res, { flash });
      return;
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async resetPassword(req, res) {
    try {
      const reset = await this.passwordReset(req, constants.ROLE_STAFF);
      if (reset.success) {
        Response.success(res, {
          message: "Password reset successful. Please login again.",
        });
      }
      Response.error(res, "RESET_FAILED", reset.message, 400);
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async resetHostPassword(req, res) {
    try {
      const reset = await this.passwordReset(req, constants.ROLE_HOST);
      if (reset.success) {
        Response.success(res, {
          message: "Password reset successful. Please login again.",
        });
      }
      return res.status(400).json({ error: reset.message });
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async passwordReset(req, role) {
    try {
      const { email, otp, new_password, confirm_password } = req.body;

      if (!email || !otp || !new_password || !confirm_password) {
        return { success: false, message: "Mandatory fields missing" };
      }
      var user = await User.find("users", { email: email, role });

      if (!user) {
        return { success: false, message: "Unrecognised email" };
      }
      const otpRecord = await User.getOTPRecord({ user_id: user.id });
      const currentTime = Math.round(Date.now() / 1000);

      if (!otpRecord || otpRecord.length == 0 || otpRecord.otp != otp) {
        return { success: false, message: "OTP is Incorrect" };
      }
      if (currentTime >= otpRecord.expires_at) {
        return { success: false, message: "OTP has expired" };
      }
      if (new_password != confirm_password) {
        return { success: false, message: "Passwords do not match" };
      }
      user.password = await bcrypt.hash(new_password, 10);
      User.update("users", user, user.id);
      return { success: true, message: "Password reset successfull" };
    } catch (error) {
      return { success: false, message: "Internal server error" };
    }
  }

  async guests(req, res) {
    try {
      const { recent, upcoming, ongoing, past } =
        await User.guestsForDashboard();
      await res.render("guests/list.ejs", { recent, upcoming, ongoing, past });
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async users(req, res) {
    var { type, flash } = req.params;
    if (!flash) {
      flash = "";
    }
    var users = [];
    if (type == "staff") {
      users = await User.getStaffWithDetails();
    }
    if (type == "host") {
      const hosts = await User.getHostsWithDetails();
      const countries = await SMModel.getFromTable("settings", {
        setting: "countries",
      });
      const allProperties = await Property.propertiesList();
      const property_hosts = await SMModel.getFromTable("property_hosts");
      hosts.forEach((user) => {
        const selectedcountry = countries.find(
          (country) => country.id == user.country,
        );
        user["selectedcountry"] = "";
        if (selectedcountry) {
          user["selectedcountry"] = selectedcountry.display;
        }
        var hostProps = property_hosts.filter((ph) => ph.host_id == user.id);
        hostProps = hostProps.map((p) => p.property_id);
        const properties = allProperties.filter((p) =>
          hostProps.includes(p.id),
        );
        user["properties"] = properties
          .map((a) => `${a.listing_name}`)
          .join("<br>");
        users.push(user);
      });
    }
    await res.render("users/list.ejs", { users, type, flash });
  }

  async add(req, res) {
    const { type } = req.params;
    const results = await SettingsHelper.consolidatedSettingsWithUsers();
    const allProperties = await Property.propertiesList();
    await res.render("users/add.ejs", {
      type,
      results,
      allProperties,
      defaultCountry: 14,
    });
  }

  async create(req, res) {
    try {
      const { firstname, lastname, email, phone, password, type } = req.body;
      if (
        !firstname ||
        firstname == "" ||
        !lastname ||
        lastname == "" ||
        !email ||
        email == "" ||
        !phone ||
        phone == ""
      ) {
        Response.error(
          res,
          "VALIDATION_ERROR",
          "Mandatory booking parameters missing or incorrect!",
        );

        return;
      }
      //validate email and phone unique
      const values = {};
      if (!password || password == "") {
        res.status(200).json({
          success: false,
          error: "Mandatory booking parameters missing or incorrect!",
        });
      } else {
        values["password"] = await bcrypt.hash(password, 10);
      }
      userFields.forEach((fieldName) => {
        if (Object.hasOwnProperty.bind(req.body)(fieldName)) {
          values[fieldName] = req.body[fieldName];
        }
      });
      if (req.body.date_of_birth && req.body.date_of_birth != "") {
        values.date_of_birth = format(req.body.date_of_birth, "yyyy-MM-dd");
      }
      if (req.body.date_of_joining && req.body.date_of_joining != "") {
        values.date_of_joining = format(req.body.date_of_joining, "yyyy-MM-dd");
      }
      values["role"] = userRoles[type];

      //const user = await SMModel.writeTableEntry('users',values);
      const userId = await User.insert("users", values);
      const user = await User.find("users", { id: userId });
      if (type == "host") {
        var properties = [];
        if (req.body.properties) {
          properties = req.body.properties;
        }
        await SMModel.updateOneToManyEntries(
          "property_hosts",
          "host_id",
          user.id,
          "property_id",
          properties,
        );
      }
      Response.success(res, {
        user,
        flash: `Successfully added ${firstname} ${lastname}`,
      });
    } catch (error) {
      res.status(400).json({ success: false, error: "Failed to create user" });
    }
  }

  async edit(req, res) {
    const { id } = req.params;
    const results = await SettingsHelper.consolidatedSettingsWithUsers();
    const user = await SMModel.getRowByUniqueId("users", id);
    const allProperties = await Property.propertiesList();
    if (user.date_of_birth) {
      user.date_of_birth = format(user.date_of_birth, "dd MMM yyyy");
    }
    if (user.date_of_joining) {
      user.date_of_joining = format(user.date_of_joining, "dd MMM yyyy");
    }
    var selectedCountry = 0;
    if (user.country) {
      const country = await SMModel.getRowByUniqueId("settings", user.country);
      selectedCountry = country.id;
    }
    const type = userTypes[user.role];
    if (type == "host") {
      const hostProps = await SMModel.getFromTable("property_hosts", {
        host_id: id,
      });
      user["hostProps"] = hostProps.map((p) => p.property_id);
    }
    await res.render("users/edit.ejs", {
      type,
      results,
      user,
      selectedCountry,
      allProperties,
    });
  }

  async save(req, res) {
    try {
      const { id, type } = req.body;
      const { firstname, lastname, email, phone } = req.body;
      if (
        !firstname ||
        firstname == "" ||
        !lastname ||
        lastname == "" ||
        !email ||
        email == "" ||
        !phone ||
        phone == ""
      ) {
        res.status(200).json({
          success: false,
          error: "Mandatory booking parameters missing or incorrect!",
        });
        return;
      }
      //validate email and phone unique
      const values = {};
      userFields.forEach((fieldName) => {
        if (Object.hasOwnProperty.bind(req.body)(fieldName)) {
          values[fieldName] = req.body[fieldName];
        }
      });
      values.date_of_birth = null;
      if (req.body.date_of_birth && req.body.date_of_birth != "") {
        values.date_of_birth = format(req.body.date_of_birth, "yyyy-MM-dd");
      }
      values.date_of_joining = null;
      if (req.body.date_of_joining && req.body.date_of_joining != "") {
        values.date_of_joining = format(req.body.date_of_joining, "yyyy-MM-dd");
      }

      const user = await User.update("users", values, id);
      if (type == "host") {
        var properties = [];
        if (req.body.properties) {
          properties = req.body.properties;
        }
        await User.updateOneToManyEntries(
          "property_hosts",
          "host_id",
          id,
          "property_id",
          properties,
        );
      }
      Response.success(res, {
        user,
        flash: `${firstname} ${lastname} was updated`,
      });
    } catch (error) {
      res.status(400).json({ success: false, error: "Failed to update user" });
    }
  }

  async userDetails(req, res) {
    const { id } = req.params;
    try {
      const booking = await SMModel.getRowByUniqueId("bookings", id);
      booking["formated_reservation_date"] = format(
        booking.createDatetime,
        "dd/MM/yyyy",
      );
      booking["formated_start_date"] = format(booking.start, "dd/MM/yyyy");
      booking["formated_end_date"] = format(booking.end, "dd/MM/yyyy");
      booking["nights"] = differenceInDays(booking.end, booking.start);
      const user = await SMModel.getRowByUniqueId("users", booking.guest_id);
      const property = await SMModel.getRowByUniqueId(
        "properties",
        booking.property_id,
      );
      const registration = await SMModel.getRowByUniqueId(
        "booking_registrations",
        id,
        "booking_id",
      );
      const rental = await SMModel.getFromTable("booking_rentalInfo", {
        booking_id: id,
        effectiveDate: format(booking.start, "yyyy-MM-dd"),
      });
      const amenities = await Property.amenitiesByProperty(booking.property_id);
      const property_type = await Setting.display(
        "property_type",
        property.property_type,
      );
      const destination = await SMModel.getRowByUniqueId(
        "destinations",
        property.destination,
      );
      await res.render("guests/edit.ejs", {
        booking,
        user,
        property,
        registration,
        rental: rental[0],
        amenities,
        property_type,
        destination: destination.name,
      });
    } catch (error) {
      res
        .status(400)
        .json({ success: false, error: "Error while fetching details" });
    }
  }

  async editHost(req, res) {
    try {
      const result = await User.find("users", { id: req.guest.id });
      if (result) {
        const user = {};
        hostFields.forEach((fieldName) => {
          if (Object.hasOwnProperty.bind(result)(fieldName)) {
            user[fieldName] = result[fieldName];
          }
        });
        Response.success(res, user);
      }
      Response.error(res, "NOT_FOUND", "Unknown user", 400);
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async updateHost(req, res) {
    try {
      const user = {};
      hostFields.forEach((fieldName) => {
        if (Object.hasOwnProperty.bind(req.body)(fieldName)) {
          user[fieldName] = req.body[fieldName];
        }
      });
      const result = await User.update("users", user, req.guest.id);
      return res.status(200).json({ success: true, user });
    } catch (error) {
      res.status(500).json({ error: "Internal server error" });
    }
  }

  async apiRegisterUser(req, res) {
    try {
      const { firstname, lastname, email, password, role } = req.body;
      if (!firstname || !lastname || !email || !password) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "Please fill required fields!",
          400,
        );
      }
      const userAvailable = await User.userExists(email);
      console.log(userAvailable);
      if (userAvailable) {
        return Response.error(res, "USER_EXISTS", "User already registered.", 400);
      }

      //Hash password
      const hashedPassword = await bcrypt.hash(password, 10);
      const newUser = await User.create({
        firstname,
        lastname,
        email,
        password: hashedPassword,
        role,
      });
      if (newUser) {
        return Response.success(res, {
          id: newUser.id,
          email: newUser.email,
          name: newUser.firstname + " " + newUser.lastname,
        });
      } else {
        return res.status(400).json({ message: "Invalid user data" });
      }
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to register user", 500);
    }
  }

  async apiRegisterWithPhone(req, res) {
    try {
      const { phone } = req.body;
      if (!phone) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "Phone number missing or invalid!",
          400,
        );
      }
      const userAvailable = await User.userPhoneExists(phone);
      if (userAvailable) {
        return Response.error(
          res,
          "USER_EXISTS",
          "User already registered. Please login",
          400,
        );
      }
      const newUser = await User.createWithPhone(phone, "268");
      if (newUser) {
        return Response.success(res, { id: newUser.id });
      } else {
        return res.status(400).json({ message: "Invalid user data" });
      }
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to register with phone", 500);
    }
  }

  async apiLoginUser(req, res) {
    try {
      const { email, password } = req.body;
      if (!email || !password) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "Please fill required fields!",
          400,
        );
      }
      const userAvailable = await User.getByEmail(email);
      if (
        userAvailable &&
        (await bcrypt.compare(password, userAvailable.password))
      ) {
        const accessToken = jwt.sign(
          {
            user: {
              email: userAvailable.email,
              id: userAvailable.id,
            },
          },
          process.env.ACCESS_TOKEN_SECRET,
          { expiresIn: "300m" },
        );
        return Response.success(res, { accessToken });
      } else {
        res.status(401).json({ message: "Wrong email or password" });
      }
    } catch (error) {
      res.status(500).json({ message: "Internal server error" });
    }
  }

  async apiCurrentUser(req, res) {
    try {
      return Response.success(res, req.user);
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to fetch current user", 500);
    }
  }

  async apiGenerateToken(req, res) {
    try {
      const accessToken = jwt.sign(
        {
          user: {
            email: "host_api@thestaymaster.com",
            id: 21,
          },
        },
        process.env.ACCESS_TOKEN_SECRET,
      );
      return Response.success(res, { token: accessToken });
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to generate token", 500);
    }
  }

  async apiCheck(req, res) {
    try {
      return Response.success(res, { user: req.user });
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Auth check failed", 500);
    }
  }

  async apiGetProfile(req, res) {
    try {
      const { id } = req.body;
      if (!id) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "id is a required field!",
          400,
        );
      }
      const userAvailable = await User.getById(id);
      if (!userAvailable || userAvailable.length == 0) {
        return Response.error(res, "NOT_FOUND", "User not found", 404);
      }
      const u = userAvailable[0];
      return Response.success(res, {
        id: u.id,
        firstname: u.firstname,
        lastname: u.lastname,
        email: u.email,
        phone: u.phone,
      });
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to get profile", 500);
    }
  }

  async apiUpdateProfile(req, res) {
    try {
      const { id, firstname, lastname, email, phone } = req.body;
      if (!id || !firstname || !lastname || !email || !phone) {
        return Response.error(
          res,
          "VALIDATION_ERROR",
          "Please fill required fields!",
          400,
        );
      }
      const userAvailable = await User.getById(id);
      if (!userAvailable || userAvailable.length == 0) {
        return res.status(400).json({ message: "User not found" });
      }
      if (firstname === null || firstname.length === 0) {
        return res.status(400).json({ message: "First name field required!" });
      }
      if (lastname === null || lastname.length === 0) {
        return res.status(400).json({ message: "Last name field required!" });
      }
      if (email === null || email.length === 0) {
        return res.status(400).json({ message: "email field required!" });
      }
      if (phone === null || phone.length === 0) {
        return res.status(400).json({ message: "phone field required!" });
      }
      await User.updateProfile(id, firstname, lastname, email, phone);
      return Response.success(res, {
        message: "Updated successfully",
      });
    } catch (error) {
      Response.error(res, "SERVER_ERROR", "Failed to update profile", 500);
    }
  }

  async checkEmail(req, res) {
    try {
      const body1 = `<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Booking Confirmation</title>
  </head>
  <body style="margin:0; padding:0; font-family: Arial, sans-serif; background-color: #f5f5f5;">
    <table width="100%" cellpadding="0" cellspacing="0" style="background-color:#f5f5f5; padding:20px;">
      <tr>
        <td align="center">
          <table width="600" cellpadding="0" cellspacing="0" style="background-color:#ffffff; padding:20px; border-radius:8px;">
            <!-- Header -->
            <tr>
              <td align="center" style="padding:20px 0; background-color:#008281; color:#ffffff; font-size:24px; font-weight:bold;">
                Booking Confirmation
              </td>
            </tr>

            <!-- Booking Info -->
            <tr>
              <td style="padding:20px;">
                <h2 style="margin-top:0;">Property: {{property_name}}</h2>
                <p><strong>Check-In:</strong> {{check_in_date}}</p>
                <p><strong>Check-Out:</strong> {{check_out_date}}</p>
                <p><strong>No. of Nights:</strong> {{nights}}</p>
                <p><strong>Total Amount:</strong> {{total_amount}}</p>
                <p><strong>Paid Amount:</strong> {{paid_amount}}</p>
                <p>We acknowledge the receipt of your payment and confirm your booking.</p>
              </td>
            </tr>

            <!-- Property Info -->
            <tr>
              <td style="padding:20px; background-color:#f0f0f0;">
                <h3 style="margin-top:0;">Property Address</h3>
                <p>{{property_address}}</p>
                <p><a href="{{google_maps_link}}" style="color:#003366; text-decoration:underline;">View on Google Maps</a></p>

                <h3>Hospitality Manager Contact</h3>
                <p>{{manager_name}}<br/>Phone: {{manager_phone}}<br/>Email: {{manager_email}}</p>
              </td>
            </tr>

            <!-- Rules & Terms -->
            <tr>
              <td style="padding:20px;">
                <h3>House Rules</h3>
                <ul style="padding-left:20px;">
                  <li>No smoking inside the property</li>
                  <li>No pets allowed</li>
                  <li>Quiet hours after 10 PM</li>
                  <!-- Add more as needed -->
                </ul>

                <h3>Security Deposit</h3>
                <p>A refundable security deposit of {{security_deposit}} will be held during your stay.</p>

                <h3>Terms & Conditions</h3>
                <p>
                  Please review our <a href="{{terms_link}}" style="color:#003366;">full terms and conditions</a> before your stay. By confirming this booking, you agree to comply with all house rules and policies.
                </p>
              </td>
            </tr>

            <!-- Footer -->
            <tr>
              <td align="center" style="padding:20px; font-size:12px; color:#888888;">
                © {{year}} Your Company Name. All rights reserved.
              </td>
            </tr>

          </table>
        </td>
      </tr>
    </table>
  </body>
</html>`;

      const body2 = `<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Booking Confirmation</title>
  </head>
  <body style="margin:0; padding:0; background-color:#f4f4f4; font-family:'Segoe UI', sans-serif;">
    <table width="100%" cellpadding="0" cellspacing="0" style="background-color:#f4f4f4; padding:30px 0;">
      <tr>
        <td align="center">
          <table width="600" cellpadding="0" cellspacing="0" style="background:#ffffff; border-radius:10px; overflow:hidden; box-shadow:0 0 8px rgba(0,0,0,0.05);">
            
            <!-- Header -->
            <tr>
              <td align="center" style="background-color:#1e2a38; padding:30px;">
                <h1 style="color:#ffffff; font-size:24px; margin:0;">Booking Confirmed</h1>
                <p style="color:#d1d1d1; margin:5px 0 0;">Thank you for choosing {{property_name}}</p>
              </td>
            </tr>

            <!-- Booking Details -->
            <tr>
              <td style="padding:30px;">
                <h2 style="color:#333; font-size:18px; margin:0 0 15px;">Reservation Summary</h2>
                <table width="100%" cellpadding="0" cellspacing="0" style="font-size:14px; color:#555;">
                  <tr>
                    <td style="padding:5px 0;"><strong>Check-In:</strong></td>
                    <td style="padding:5px 0;">{{check_in_date}}</td>
                  </tr>
                  <tr>
                    <td style="padding:5px 0;"><strong>Check-Out:</strong></td>
                    <td style="padding:5px 0;">{{check_out_date}}</td>
                  </tr>
                  <tr>
                    <td style="padding:5px 0;"><strong>No. of Nights:</strong></td>
                    <td style="padding:5px 0;">{{nights}}</td>
                  </tr>
                  <tr>
                    <td style="padding:5px 0;"><strong>Total Amount:</strong></td>
                    <td style="padding:5px 0;">{{total_amount}}</td>
                  </tr>
                  <tr>
                    <td style="padding:5px 0;"><strong>Paid Amount:</strong></td>
                    <td style="padding:5px 0;">{{paid_amount}}</td>
                  </tr>
                </table>
                <p style="margin-top:20px; color:#333;">We acknowledge receipt of your payment and look forward to hosting you.</p>
              </td>
            </tr>

            <!-- Property Info -->
            <tr>
              <td style="background-color:#f9f9f9; padding:30px;">
                <h2 style="margin-top:0; font-size:18px; color:#333;">Property Details</h2>
                <p style="margin:5px 0;"><strong>Address:</strong><br/>{{property_address}}</p>
                <p style="margin:10px 0;">
                  <a href="{{google_maps_link}}" style="color:#1e2a38; text-decoration:none;">📍 View on Google Maps</a>
                </p>

                <h3 style="margin-top:25px; font-size:16px; color:#333;">Hospitality Manager</h3>
                <p style="margin:5px 0;">{{manager_name}}<br/>📞 {{manager_phone}}<br/>📧 {{manager_email}}</p>
              </td>
            </tr>

            <!-- House Rules & Terms -->
            <tr>
              <td style="padding:30px;">
                <h2 style="font-size:18px; color:#333;">Important Information</h2>

                <h3 style="margin-bottom:5px;">🏠 House Rules</h3>
                <ul style="padding-left:20px; margin-top:5px; color:#555;">
                  <li>No smoking inside the property</li>
                  <li>No pets allowed</li>
                  <li>Quiet hours: 10:00 PM – 8:00 AM</li>
                </ul>

                <h3 style="margin:20px 0 5px;">💰 Security Deposit</h3>
                <p style="margin:0; color:#555;">A refundable deposit of <strong>{{security_deposit}}</strong> will be held and returned post-inspection.</p>

                <h3 style="margin:20px 0 5px;">📄 Terms & Conditions</h3>
                <p style="margin:0;">
                  By confirming your booking, you agree to our 
                  <a href="{{terms_link}}" style="color:#1e2a38; text-decoration:underline;">terms & conditions</a> and house policies.
                </p>
              </td>
            </tr>

            <!-- Footer -->
            <tr>
              <td align="center" style="background-color:#1e2a38; color:#ccc; padding:20px; font-size:12px;">
                © {{year}} Your Company Name. All rights reserved.
              </td>
            </tr>

          </table>
        </td>
      </tr>
    </table>
  </body>
</html>
`;
      const body3 = `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Booking Confirmation</title>
  <style>
    /* Mobile Styles */
    @media only screen and (max-width: 720px) {
      .container {
        width: 100% !important;
        padding: 0 15px !important;
      }
      .content, .footer {
        padding: 20px !important;
      }
      h1 {
        font-size: 22px !important;
      }
      h2 {
        font-size: 18px !important;
      }
      h3 {
        font-size: 16px !important;
      }
    }
  </style>
</head>
<body style="margin:0; padding:0; background-color:#f4f4f4; font-family:'Segoe UI', sans-serif;">
  <table width="100%" cellpadding="0" cellspacing="0" style="background-color:#f4f4f4; padding:30px 0;">
    <tr>
      <td align="center">
        <table class="container" width="700" cellpadding="0" cellspacing="0" style="background:#ffffff; border-radius:10px; overflow:hidden; box-shadow:0 0 8px rgba(0,0,0,0.05); width:700px;">
          
          <!-- Header -->
          <tr>
            <td align="center" style="background-color:#1e2a38; padding:30px;">
              <h1 style="color:#ffffff; font-size:26px; margin:0;">Booking Confirmed</h1>
              <p style="color:#d1d1d1; margin:5px 0 0;">Thank you for choosing {{property_name}}</p>
            </td>
          </tr>

          <!-- Booking Details -->
          <tr>
            <td class="content" style="padding:30px;">
              <h2 style="color:#333; font-size:20px; margin:0 0 15px;">Reservation Summary</h2>
              <table width="100%" cellpadding="0" cellspacing="0" style="font-size:15px; color:#555;">
                <tr>
                  <td style="padding:5px 0;"><strong>Check-In:</strong></td>
                  <td style="padding:5px 0;">{{check_in_date}}</td>
                </tr>
                <tr>
                  <td style="padding:5px 0;"><strong>Check-Out:</strong></td>
                  <td style="padding:5px 0;">{{check_out_date}}</td>
                </tr>
                <tr>
                  <td style="padding:5px 0;"><strong>No. of Nights:</strong></td>
                  <td style="padding:5px 0;">{{nights}}</td>
                </tr>
                <tr>
                  <td style="padding:5px 0;"><strong>Total Amount:</strong></td>
                  <td style="padding:5px 0;">{{total_amount}}</td>
                </tr>
                <tr>
                  <td style="padding:5px 0;"><strong>Paid Amount:</strong></td>
                  <td style="padding:5px 0;">{{paid_amount}}</td>
                </tr>
              </table>
              <p style="margin-top:20px; color:#333;">We acknowledge receipt of your payment and look forward to hosting you.</p>
            </td>
          </tr>

          <!-- Property Info -->
          <tr>
            <td class="content" style="background-color:#f9f9f9; padding:30px;">
              <h2 style="margin-top:0; font-size:20px; color:#333;">Property Details</h2>
              <p style="margin:5px 0;"><strong>Address:</strong><br/>{{property_address}}</p>
              <p style="margin:10px 0;">
                <a href="{{google_maps_link}}" style="color:#1e2a38; text-decoration:none;">📍 View on Google Maps</a>
              </p>

              <h3 style="margin-top:25px; font-size:17px; color:#333;">Hospitality Manager</h3>
              <p style="margin:5px 0;">{{manager_name}}<br/>📞 {{manager_phone}}<br/>📧 {{manager_email}}</p>
            </td>
          </tr>

          <!-- House Rules & Terms -->
          <tr>
            <td class="content" style="padding:30px;">
              <h2 style="font-size:20px; color:#333;">Important Information</h2>

              <h3 style="margin-bottom:5px;">🏠 House Rules</h3>
              <ul style="padding-left:20px; margin-top:5px; color:#555;">
                <li>No smoking inside the property</li>
                <li>No pets allowed</li>
                <li>Quiet hours: 10:00 PM – 8:00 AM</li>
              </ul>

              <h3 style="margin:20px 0 5px;">💰 Security Deposit</h3>
              <p style="margin:0; color:#555;">A refundable deposit of <strong>{{security_deposit}}</strong> will be held and returned post-inspection.</p>

              <h3 style="margin:20px 0 5px;">📄 Terms & Conditions</h3>
              <p style="margin:0;">
                By confirming your booking, you agree to our 
                <a href="{{terms_link}}" style="color:#1e2a38; text-decoration:underline;">terms & conditions</a> and house policies.
              </p>
            </td>
          </tr>

          <!-- Footer -->
          <tr>
            <td class="footer" align="center" style="background-color:#1e2a38; color:#ccc; padding:20px; font-size:12px;">
              © {{year}} Your Company Name. All rights reserved.
            </td>
          </tr>

        </table>
      </td>
    </tr>
  </table>
</body>
</html>
`;
      //await Utility.sendEMail('rakeshkamat@gmail.com','Test Conf 1',body1);
      await Utility.sendEMail(
        "rakeshkamat@gmail.com",
        "Booking Confirmation from Staymaster",
        body3,
      );
      res
        .status(200)
        .json({ success: true, message: "Email sent successfully" });
    } catch (error) {
      res
        .status(400)
        .json({ success: false, message: "Please try after some time" });
    }
  }
}
module.exports = UsersController;

// Backward-compatible named exports for route files
const _instance = new UsersController();
module.exports.registerUser = _instance.apiRegisterUser.bind(_instance);
module.exports.registerWithPhone = _instance.apiRegisterWithPhone.bind(_instance);
module.exports.loginUser = _instance.apiLoginUser.bind(_instance);
module.exports.currentUser = _instance.apiCurrentUser.bind(_instance);
module.exports.generateToken = _instance.apiGenerateToken.bind(_instance);
module.exports.check = _instance.apiCheck.bind(_instance);
module.exports.getProfile = _instance.apiGetProfile.bind(_instance);
module.exports.updateProfile = _instance.apiUpdateProfile.bind(_instance);
