const { pool } = require("../../config/db");

const createVisitor = async (req, res) => {
  const userId = req.session?.user?.id || null;
  const orgId = req.session?.user?.orgId;
  try {
    const {
      visitorName,
      phoneNumber,
      company,
      vehicleNumber,
      hostId,
      purpose,
      parkingAllocation,
    } = req.body;

    //  Basic validation
    if (!visitorName || !phoneNumber) {
      return res.status(400).json({
        success: false,
        message: "Visitor name and phone number are required",
      });
    }

    //  Normalize (good practice)
    const formattedVehicle =
      vehicleNumber?.replace(/\s+/g, "").toUpperCase() || null;

    const photo = req.file ? req.file.path : null;

    //  Insert query
    const query = `
      INSERT INTO visitors (
        photo,
        visitor_name,
        phone_number,
        company,
        vehicle_number,
        host_id,
        host_detail_name,
        purpose,
        parking_allocation,
        org_id, 
        created_by,
        updated_by,
        created_at,
        updated_at
      )
      VALUES (
        $1, $2, $3, $4, $5,
        $6, $7, $8, $9,
        $10, $11,$12, NOW(), NOW()
      )
      RETURNING *;
    `;

    const values = [
      photo,
      visitorName,
      phoneNumber,
      company || null,
      formattedVehicle,
      hostId || null, //  NULL allowed
      null, // host_detail_name (no users table yet)
      purpose || null,
      parkingAllocation || "No Vehicle",
      Number(orgId), // org_id
      userId, // created_by
      userId, // updated_by
    ];

    const result = await pool.query(query, values);

    return res.status(201).json({
      success: true,
      message: "Visitor registered successfully",
      data: result.rows[0],
    });
  } catch (error) {
    console.error("Create Visitor Error:", error);

    return res.status(500).json({
      success: false,
      message: "Failed to register visitor",
    });
  }
};

const getVisitors = async (req, res) => {
  try {
    const page = parseInt(req.query.page, 10) || 1;
    const limit = parseInt(req.query.limit, 10) || 10;

    const offset = (page - 1) * limit;

    // Fetch visitors (with optional host name)
    const dataQuery = `
      SELECT 
        v.*,
        u.name AS host_name
      FROM visitors v
      LEFT JOIN users u ON v.host_id = u.id
      WHERE v.is_deleted = FALSE
      ORDER BY v.created_at DESC
      LIMIT $1 OFFSET $2;
    `;

    const dataResult = await pool.query(dataQuery, [limit, offset]);

    // Total count
    const countQuery = `
      SELECT COUNT(*) AS total
      FROM visitors
      WHERE is_deleted = FALSE;
    `;

    const countResult = await pool.query(countQuery);
    const total = parseInt(countResult.rows[0].total, 10);

    return res.status(200).json({
      success: true,
      data: dataResult.rows,
      pagination: {
        total,
        page,
        limit,
        totalPages: Math.ceil(total / limit),
      },
    });
  } catch (error) {
    console.error("Get Visitors Error:", error);

    return res.status(500).json({
      success: false,
      message: "Failed to fetch visitors",
    });
  }
};

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

    // 1. Check visitor exists
    const visitorResult = await pool.query(
      `SELECT id, visitor_name, host_approval
       FROM visitors
       WHERE id = $1 AND is_deleted = FALSE
       LIMIT 1`,
      [id],
    );

    if (visitorResult.rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: "Visitor not found",
      });
    }

    const visitor = visitorResult.rows[0];

    // 2. Prevent double approval
    if (visitor.host_approval === "Approved") {
      return res.status(400).json({
        success: false,
        message: "Visitor already approved",
      });
    }

    // 3. Update visitor
    const updateResult = await pool.query(
      `UPDATE visitors
       SET host_approval = 'Approved',
           gate_status = 'Inside',
           updated_by = $1,
           updated_at = NOW()
       WHERE id = $2
       RETURNING *`,
      [req.user?.id || null, id],
    );

    return res.status(200).json({
      success: true,
      message: "Visitor approved successfully",
      data: updateResult.rows[0],
    });
  } catch (error) {
    console.error("Approve Visitor Error:", error);

    return res.status(500).json({
      success: false,
      message: "Failed to approve visitor",
    });
  }
};

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

    // 1. Check visitor exists
    const visitorResult = await pool.query(
      `SELECT id, visitor_name, host_approval, gate_status
       FROM visitors
       WHERE id = $1 AND is_deleted = FALSE
       LIMIT 1`,
      [id],
    );

    if (visitorResult.rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: "Visitor not found",
      });
    }

    const visitor = visitorResult.rows[0];

    // 2. Prevent exit if not approved
    if (visitor.host_approval !== "Approved") {
      return res.status(400).json({
        success: false,
        message: "Visitor not approved yet",
      });
    }

    // 3. Prevent duplicate exit
    if (visitor.gate_status === "Exited") {
      return res.status(400).json({
        success: false,
        message: "Visitor already exited",
      });
    }

    // 4. Update exit
    const updateResult = await pool.query(
      `UPDATE visitors
       SET gate_status = 'Exited',
           exit_time = NOW(),
           updated_by = $1,
           updated_at = NOW()
       WHERE id = $2
       RETURNING *`,
      [req.user?.id || null, id],
    );

    return res.status(200).json({
      success: true,
      message: "Visitor exit recorded successfully",
      data: updateResult.rows[0],
    });
  } catch (error) {
    console.error("Mark Exit Error:", error);

    return res.status(500).json({
      success: false,
      message: "Failed to mark visitor exit",
    });
  }
};

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

    // 1. Check visitor exists
    const visitorResult = await pool.query(
      `SELECT id, gate_status
       FROM visitors
       WHERE id = $1 AND is_deleted = FALSE
       LIMIT 1`,
      [id],
    );

    if (visitorResult.rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: "Visitor not found",
      });
    }

    const visitor = visitorResult.rows[0];

    // 2. Prevent delete if inside
    if (visitor.gate_status === "Inside") {
      return res.status(400).json({
        success: false,
        message: "Visitor is inside. Mark exit before delete.",
      });
    }

    //3. Soft delete
    await pool.query(
      `UPDATE visitors
       SET is_deleted = TRUE,
           updated_by = $1,
           updated_at = NOW()
       WHERE id = $2`,
      [req.user?.id || null, id],
    );

    return res.json({
      success: true,
      message: "Visitor deleted successfully",
    });
  } catch (error) {
    console.error("Delete Visitor Error:", error);

    return res.status(500).json({
      success: false,
      message: "Delete failed",
    });
  }
};

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

    // Fetch visitor (with optional host details)
    const query = `
      SELECT 
        v.*,
        u.name AS host_name,
        u.email AS host_email
      FROM visitors v
      LEFT JOIN users u ON v.host_id = u.id
      WHERE v.id = $1 AND v.is_deleted = FALSE
      LIMIT 1;
    `;

    const result = await pool.query(query, [id]);

    if (result.rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: "Visitor not found",
      });
    }

    return res.status(200).json({
      success: true,
      data: result.rows[0],
    });
  } catch (error) {
    console.error("Get Visitor By Id Error:", error);

    return res.status(500).json({
      success: false,
      message: "Failed to fetch visitor",
    });
  }
};

module.exports = {
  createVisitor,
  getVisitors,
  approveVisitor,
  markVisitorExit,
  deleteVisitor,
  getVisitorById,
};
