const dbConnect = require('../configs/dbConnection.js');

// ─────────────────────────────────────────────────────────────────────────────
// HELPER
// ─────────────────────────────────────────────────────────────────────────────

function generateAgentId(uid) {
  const year = new Date().getFullYear();
  return `BRS-${year}-${String(uid).padStart(6, '0')}`;
}

// ─────────────────────────────────────────────────────────────────────────────
// 1. GET /admin/agents — all agents + docs + services
// ─────────────────────────────────────────────────────────────────────────────

exports.getAllAgents = async (req, res) => {
  try {
    const { status, page = 1, limit = 20 } = req.query;
    const offset = (parseInt(page) - 1) * parseInt(limit);

    let whereClause = `WHERE a.did = 'Admin'`;
    const params = [];

    if (status) {
      whereClause += ` AND a.ustatus = ?`;
      params.push(status);
    }

    const [agents] = await dbConnect.query(
      `SELECT
        a.uid, a.uname, a.umail, a.umob,
        a.uflag, a.ustatus, a.agentId, a.onboardingStatus,
        a.businessName, a.legalName, a.legalEntityType,
        a.businessCity, a.businessState,
        a.repName, a.repDesignation, a.repMobile, a.repEmail,
        a.isGstRegistered, a.gstNumber, a.panNumber,
        a.activatedAt, a.pwdchangedate AS registeredAt,
        d.verificationStatus, d.adminRemarks,
        d.uploadedAt, d.reviewedAt, d.reviewedBy,
        d.panCardUrl, d.gstCertificateUrl,
        d.incorporationCertificateUrl, d.partnershipDeedUrl,
        d.businessProofUrl, d.letterHeadUrl,
        d.addressProofUrl, d.cancelledChequeUrl,
        d.representativeIdProofUrl, d.legalNameDocumentUrl,
        d.udyamCertificateUrl,
        s.bus, s.flights, s.hotels, s.holidays,
        s.cabs, s.bill_payments, s.it_services
       FROM alogin a
       LEFT JOIN agentSignUpDocument d ON d.temporaryRegistrationId = a.uid
       LEFT JOIN agent_services s ON s.uid = a.uid
       ${whereClause}
       ORDER BY a.uid DESC
       LIMIT ? OFFSET ?`,
      [...params, parseInt(limit), offset]
    );

    const [[{ total }]] = await dbConnect.query(
      `SELECT COUNT(*) AS total FROM alogin a WHERE a.did = 'Admin'
       ${status ? 'AND a.ustatus = ?' : ''}`,
      status ? [status] : []
    );

    return res.status(200).json({
      agents,
      pagination: {
        total,
        page: parseInt(page),
        limit: parseInt(limit),
        totalPages: Math.ceil(total / parseInt(limit)),
      },
    });
  } catch (error) {
    console.error('Error in getAllAgents:', error);
    return res.status(500).json({ error: error.message });
  }
};

// ─────────────────────────────────────────────────────────────────────────────
// 2. GET /admin/agents/:userId — single agent full details
// ─────────────────────────────────────────────────────────────────────────────

exports.getAgentById = async (req, res) => {
  try {
    const { userId } = req.params;

    const [rows] = await dbConnect.query(
      `SELECT
        a.uid, a.uname, a.umail, a.umob,
        a.uflag, a.ustatus, a.agentId, a.onboardingStatus,
        a.businessName, a.proprietorshipName, a.tradeName,
        a.legalName, a.legalEntityType,
        a.businessAddress, a.businessCity, a.businessState,
        a.businessPinCode, a.businessCountry,
        a.repName, a.repDesignation, a.repMobile, a.repEmail,
        a.isGstRegistered, a.gstNumber, a.panNumber, a.udyamNumber,
        a.activatedAt, a.pwdchangedate AS registeredAt,
        d.verificationStatus, d.adminRemarks,
        d.uploadedAt, d.reviewedAt, d.reviewedBy,
        d.panCardUrl, d.gstCertificateUrl,
        d.incorporationCertificateUrl, d.partnershipDeedUrl,
        d.businessProofUrl, d.letterHeadUrl,
        d.addressProofUrl, d.cancelledChequeUrl,
        d.representativeIdProofUrl, d.legalNameDocumentUrl,
        d.udyamCertificateUrl,
        s.bus, s.flights, s.hotels, s.holidays,
        s.cabs, s.bill_payments, s.it_services
       FROM alogin a
       LEFT JOIN agentSignUpDocument d ON d.temporaryRegistrationId = a.uid
       LEFT JOIN agent_services s ON s.uid = a.uid
       WHERE a.uid = ?`,
      [userId]
    );

    if (rows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }

    // Separate into clean sections
    const row = rows[0];
    return res.status(200).json({
      agent: {
        uid: row.uid, uname: row.uname, umail: row.umail, umob: row.umob,
        uflag: row.uflag, ustatus: row.ustatus, agentId: row.agentId,
        onboardingStatus: row.onboardingStatus, registeredAt: row.registeredAt,
        activatedAt: row.activatedAt,
      },
      business: {
        businessName: row.businessName, proprietorshipName: row.proprietorshipName,
        tradeName: row.tradeName, legalName: row.legalName,
        legalEntityType: row.legalEntityType,
        businessAddress: row.businessAddress, businessCity: row.businessCity,
        businessState: row.businessState, businessPinCode: row.businessPinCode,
        businessCountry: row.businessCountry,
        repName: row.repName, repDesignation: row.repDesignation,
        repMobile: row.repMobile, repEmail: row.repEmail,
        isGstRegistered: row.isGstRegistered, gstNumber: row.gstNumber,
        panNumber: row.panNumber, udyamNumber: row.udyamNumber,
      },
      documents: {
        verificationStatus: row.verificationStatus,
        adminRemarks: row.adminRemarks,
        uploadedAt: row.uploadedAt,
        reviewedAt: row.reviewedAt,
        reviewedBy: row.reviewedBy,
        panCardUrl: row.panCardUrl,
        gstCertificateUrl: row.gstCertificateUrl,
        incorporationCertificateUrl: row.incorporationCertificateUrl,
        partnershipDeedUrl: row.partnershipDeedUrl,
        businessProofUrl: row.businessProofUrl,
        letterHeadUrl: row.letterHeadUrl,
        addressProofUrl: row.addressProofUrl,
        cancelledChequeUrl: row.cancelledChequeUrl,
        representativeIdProofUrl: row.representativeIdProofUrl,
        legalNameDocumentUrl: row.legalNameDocumentUrl,
        udyamCertificateUrl: row.udyamCertificateUrl,
      },
      services: {
        bus: row.bus, flights: row.flights, hotels: row.hotels,
        holidays: row.holidays, cabs: row.cabs,
        bill_payments: row.bill_payments, it_services: row.it_services,
      },
    });
  } catch (error) {
    console.error('Error in getAgentById:', error);
    return res.status(500).json({ error: error.message });
  }
};

// ─────────────────────────────────────────────────────────────────────────────
// 3. POST /admin/agents/:userId/approve
// Approve → generate agentId → activate
// ─────────────────────────────────────────────────────────────────────────────

exports.approveAgent = async (req, res) => {
  try {
    const { userId } = req.params;
    const { approvedBy, remarks } = req.body;

    if (!approvedBy) {
      return res.status(400).json({ error: 'approvedBy is required' });
    }

    const [userRows] = await dbConnect.query(
      `SELECT uid, uname, umail, umob, uflag, agentId FROM alogin WHERE uid = ?`,
      [userId]
    );
    if (userRows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }

    const agent = userRows[0];
  if (agent.ustatus === 'ACTIVATED') {
  return res.status(409).json({ error: 'Agent already activated', agentId: agent.agentId });
}

    const permanentAgentId = generateAgentId(userId);

    const conn = await dbConnect.getConnection();
    try {
      await conn.beginTransaction();

      await conn.query(
        `UPDATE alogin SET
          uflag = 'Active',
          ustatus = 'ACTIVATED',
          onboardingStatus = 'Activated',
          agentId = ?,
          activatedAt = NOW()
        WHERE uid = ?`,
        [permanentAgentId, userId]
      );

      await conn.query(
        `UPDATE agentSignUpDocument SET
          verificationStatus = 'Approved',
          adminRemarks = ?,
          reviewedBy = ?,
          reviewedAt = NOW()
        WHERE temporaryRegistrationId = ?`,
        [remarks || 'Approved by admin', approvedBy, userId]
      );

      await conn.commit();
    } catch (txErr) {
      await conn.rollback();
      throw txErr;
    } finally {
      conn.release();
    }

    return res.status(200).json({
      msg: 'Agent approved and activated successfully.',
      userId,
      agentId: permanentAgentId,
      status: 'ACTIVATED',
    });
  } catch (error) {
    console.error('Error in approveAgent:', error);
    return res.status(500).json({ error: error.message });
  }
};

// ─────────────────────────────────────────────────────────────────────────────
// 4. POST /admin/agents/:userId/reject
// ─────────────────────────────────────────────────────────────────────────────

exports.rejectAgent = async (req, res) => {
  try {
    const { userId } = req.params;
    const { rejectedBy, remarks } = req.body;

    if (!rejectedBy || !remarks) {
      return res.status(400).json({ error: 'rejectedBy and remarks are required' });
    }

    const [userRows] = await dbConnect.query(
      `SELECT uid, ustatus FROM alogin WHERE uid = ?`,
      [userId]
    );
    if (userRows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }

    const conn = await dbConnect.getConnection();
    try {
      await conn.beginTransaction();

      await conn.query(
        `UPDATE alogin SET
          ustatus = 'REJECTED',
          onboardingStatus = 'Rejected'
        WHERE uid = ?`,
        [userId]
      );

      await conn.query(
        `UPDATE agentSignUpDocument SET
          verificationStatus = 'Rejected',
          adminRemarks = ?,
          reviewedBy = ?,
          reviewedAt = NOW()
        WHERE temporaryRegistrationId = ?`,
        [remarks, rejectedBy, userId]
      );

      await conn.commit();
    } catch (txErr) {
      await conn.rollback();
      throw txErr;
    } finally {
      conn.release();
    }

    return res.status(200).json({
      msg: 'Agent rejected.',
      userId,
      status: 'REJECTED',
      remarks,
    });
  } catch (error) {
    console.error('Error in rejectAgent:', error);
    return res.status(500).json({ error: error.message });
  }
};

// ─────────────────────────────────────────────────────────────────────────────
// 5. POST /admin/agents/:userId/reupload
// ─────────────────────────────────────────────────────────────────────────────

exports.requestReupload = async (req, res) => {
  try {
    const { userId } = req.params;
    const { reviewedBy, remarks } = req.body;

    if (!reviewedBy || !remarks) {
      return res.status(400).json({ error: 'reviewedBy and remarks are required' });
    }

    const [userRows] = await dbConnect.query(
      `SELECT uid FROM alogin WHERE uid = ?`,
      [userId]
    );
    if (userRows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }

    await dbConnect.query(
      `UPDATE alogin SET
        ustatus = 'REUPLOAD_REQUESTED',
        onboardingStatus = 'Reupload Requested'
      WHERE uid = ?`,
      [userId]
    );

    await dbConnect.query(
      `UPDATE agentSignUpDocument SET
        verificationStatus = 'Reupload Required',
        adminRemarks = ?,
        reviewedBy = ?,
        reviewedAt = NOW()
      WHERE temporaryRegistrationId = ?`,
      [remarks, reviewedBy, userId]
    );

    return res.status(200).json({
      msg: 'Reupload requested.',
      userId,
      status: 'REUPLOAD_REQUESTED',
      remarks,
    });
  } catch (error) {
    console.error('Error in requestReupload:', error);
    return res.status(500).json({ error: error.message });
  }
};

// ─────────────────────────────────────────────────────────────────────────────
// 6. PUT /admin/agents/:userId/services
// Admin enable/disable services for an agent
// Body: { bus, flights, hotels, holidays, cabs, bill_payments, it_services }
// Each value: 1 (enable) or 0 (disable)
// ─────────────────────────────────────────────────────────────────────────────

exports.updateAgentServices = async (req, res) => {
  try {
    const { userId } = req.params;
    const {
      bus, flights, hotels, holidays,
      cabs, bill_payments, it_services,
    } = req.body;

    const [userRows] = await dbConnect.query(
      `SELECT uid, ustatus FROM alogin WHERE uid = ?`,
      [userId]
    );
    if (userRows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }

    // Build dynamic SET clause — only update fields that are passed
    const updates = [];
    const params = [];

    if (bus          !== undefined) { updates.push('bus = ?');          params.push(bus ? 1 : 0); }
    if (flights      !== undefined) { updates.push('flights = ?');      params.push(flights ? 1 : 0); }
    if (hotels       !== undefined) { updates.push('hotels = ?');       params.push(hotels ? 1 : 0); }
    if (holidays     !== undefined) { updates.push('holidays = ?');     params.push(holidays ? 1 : 0); }
    if (cabs         !== undefined) { updates.push('cabs = ?');         params.push(cabs ? 1 : 0); }
    if (bill_payments !== undefined){ updates.push('bill_payments = ?');params.push(bill_payments ? 1 : 0); }
    if (it_services  !== undefined) { updates.push('it_services = ?');  params.push(it_services ? 1 : 0); }

    if (updates.length === 0) {
      return res.status(400).json({ error: 'At least one service field is required' });
    }

    params.push(userId);

    await dbConnect.query(
      `UPDATE agent_services SET ${updates.join(', ')} WHERE uid = ?`,
      params
    );

    // Return updated services
    const [svcRows] = await dbConnect.query(
      `SELECT bus, flights, hotels, holidays, cabs, bill_payments, it_services
       FROM agent_services WHERE uid = ?`,
      [userId]
    );

    return res.status(200).json({
      msg: 'Services updated successfully.',
      userId,
      services: svcRows[0],
    });
  } catch (error) {
    console.error('Error in updateAgentServices:', error);
    return res.status(500).json({ error: error.message });
  }
};

//Deactivated API

exports.deactivateAgent = async (req, res) => {
  try {
    const { userId } = req.params;
    const { deactivatedBy, remarks } = req.body;

    if (!deactivatedBy) {
      return res.status(400).json({ error: 'deactivatedBy is required' });
    }

    const [userRows] = await dbConnect.query(
      `SELECT uid, ustatus, agentId FROM alogin WHERE uid = ?`,
      [userId]
    );
    if (userRows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }
    if (userRows[0].ustatus !== 'ACTIVATED') {
      return res.status(409).json({ error: 'Only activated agents can be deactivated' });
    }

    await dbConnect.query(
      `UPDATE alogin SET
        uflag = 'Inactive',
        ustatus = 'DEACTIVATED',
        onboardingStatus = 'Deactivated'
      WHERE uid = ?`,
      [userId]
    );

    return res.status(200).json({
      msg: 'Agent deactivated successfully.',
      userId,
      agentId: userRows[0].agentId,
      status: 'DEACTIVATED',
    });
  } catch (error) {
    console.error('Error in deactivateAgent:', error);
    return res.status(500).json({ error: error.message });
  }
};

// ─────────────────────────────────────────────────────────────────────────────
// 7. DELETE /admin/agents/:userId
// ─────────────────────────────────────────────────────────────────────────────

exports.deleteAgent = async (req, res) => {
  try {
    const { userId } = req.params;

    const [userRows] = await dbConnect.query(
      `SELECT uid, uname, ustatus FROM alogin WHERE uid = ?`,
      [userId]
    );
    if (userRows.length === 0) {
      return res.status(404).json({ error: 'Agent not found' });
    }

    if (userRows[0].ustatus === 'ACTIVATED') {
      return res.status(409).json({ error: 'Cannot delete an activated agent.' });
    }

    const conn = await dbConnect.getConnection();
    try {
      await conn.beginTransaction();

      await conn.query(`DELETE FROM agentSignUpDocument WHERE temporaryRegistrationId = ?`, [userId]);
      await conn.query(`DELETE FROM agent_services WHERE uid = ?`, [userId]);
      await conn.query(`DELETE FROM alogin WHERE uid = ?`, [userId]);

      await conn.commit();
    } catch (txErr) {
      await conn.rollback();
      throw txErr;
    } finally {
      conn.release();
    }

    return res.status(200).json({
      msg: `Agent ${userRows[0].uname} deleted successfully.`,
      userId,
    });
  } catch (error) {
    console.error('Error in deleteAgent:', error);
    return res.status(500).json({ error: error.message });
  }
};