const {pool} = require("../../config/db");
const parkingService = require("../../services/postgre/parkingServices")

const createBay = async (req, res) => {
  try {
    const { code, type, capacity } = req.body;

    //  Validation
    if (!code || !capacity) {
      return res.status(400).json({
        success: false,
        message: "Code and capacity are required",
      });
    }

    const formattedCode = code.trim().toUpperCase();

    //  Check if already exists (NOT DELETED)
    const existsQuery = `
      SELECT id FROM parking_bays
      WHERE code = $1 AND is_deleted = FALSE
      LIMIT 1;
    `;

    const existsResult = await pool.query(existsQuery, [formattedCode]);

    if (existsResult.rows.length > 0) {
      return res.status(400).json({
        success: false,
        message: "Bay already exists",
      });
    }

    //  Insert new bay
    const insertQuery = `
      INSERT INTO parking_bays (
        code,
        type,
        capacity,
        created_by,
        created_at,
        updated_at
      )
      VALUES ($1, $2, $3, $4, NOW(), NOW())
      RETURNING *;
    `;

    const values = [
      formattedCode,
      type || "TRUCK",
      capacity,
      req.user?.id || null,
    ];

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

    return res.status(201).json({
      success: true,
      message: "Bay created successfully",
      data: result.rows[0],
    });
  } catch (error) {
    console.error("CREATE BAY ERROR:", error);

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


const getCommercialParkingAvailability = async (req, res) => {
  try {
    const data = await parkingService.getCommercialParkingAvailability();

    res.status(200).json({
      success: true,
      message: "Parking availability fetched successfully",
      data,
    });
  } catch (error) {
    console.error(error);

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



const assignSlot = async (req, res) => {
  try {
    const { bayCode, slot, vehicleNumber } = req.body;

    // Validation
    if (!bayCode || !slot || !vehicleNumber) {
      return res.status(400).json({
        success: false,
        message: "bayCode, slot, vehicleNumber are required",
      });
    }

    // 1. Get bay
    const bayResult = await pool.query(
      `SELECT id, capacity FROM parking_bays 
       WHERE code = $1 AND is_deleted = FALSE`,
      [bayCode.trim().toUpperCase()]
    );

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

    const bay = bayResult.rows[0];

    // 2. Check if slot already occupied
    const slotCheck = await pool.query(
      `SELECT id FROM commercial_vehicles
       WHERE parking_id = $1
       AND slot = $2
       AND gate_status = 'Inside'
       AND is_deleted = FALSE
       LIMIT 1`,
      [bay.id, slot]
    );

    if (slotCheck.rows.length > 0) {
      return res.status(400).json({
        success: false,
        message: "Slot already occupied",
      });
    }

    // 3. Assign slot to vehicle
    const updateResult = await pool.query(
      `UPDATE commercial_vehicles
       SET parking_id = $1,
           slot = $2,
           updated_at = NOW()
       WHERE vehicle_number = $3
       RETURNING *`,
      [bay.id, slot, vehicleNumber.trim().toUpperCase()]
    );

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

    return res.json({
      success: true,
      message: "Slot assigned successfully",
      data: updateResult.rows[0],
    });
  } catch (error) {
    console.error("ASSIGN SLOT ERROR:", error);

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

const updateBay = async (req, res) => {
  try {
    const { id } = req.params;
    const { type, capacity, status } = req.body;

    //1. Check bay exists
    const bayResult = await pool.query(
      `SELECT id, capacity 
       FROM parking_bays 
       WHERE id = $1 AND is_deleted = FALSE`,
      [id]
    );

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

    //2. Get occupied count (vehicles inside this bay)
    const occupiedResult = await pool.query(
      `SELECT COUNT(*) AS count
       FROM commercial_vehicles
       WHERE parking_id = $1
       AND gate_status = 'Inside'
       AND is_deleted = FALSE`,
      [id]
    );

    const occupiedCount = parseInt(occupiedResult.rows[0].count, 10);

    //3. Capacity validation
    if (capacity && capacity < occupiedCount) {
      return res.status(400).json({
        success: false,
        message: `Cannot reduce capacity below occupied slots (${occupiedCount})`,
      });
    }

    //4. Update dynamically (only passed fields)
    const updateQuery = `
      UPDATE parking_bays
      SET 
        type = COALESCE($1, type),
        capacity = COALESCE($2, capacity),
        status = COALESCE($3, status),
        updated_by = $4,
        updated_at = NOW()
      WHERE id = $5
      RETURNING *;
    `;

    const values = [
      type || null,
      capacity || null,
      status || null,
      req.user?.id || null,
      id,
    ];

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

    return res.json({
      success: true,
      message: "Bay updated successfully",
      data: result.rows[0],
    });
  } catch (error) {
    console.error("UPDATE BAY ERROR:", error);

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

module.exports = {
    createBay,
    getCommercialParkingAvailability,
    assignSlot,
    updateBay,
}