import { GeneralService } from '../share/generalservice.js';
import { connection } from '../config/db.js'; 
import { sendError } from '../utils/response.js';
import { getDTM } from '../utils/date.js'; // ✅ 1. Import ฟังก์ชันกลางเข้ามา

export class BudgetExpenseService {

  constructor() {
    this.generalService = new GeneralService();
  }

  async getBudgetExpense(database, name) {
    const sql = `
      SELECT trnseq, trnprjnam
      FROM ${database}.trnmst
      WHERE trnprjnam = $1
    `;
    const params = [name];
    const result = await this.generalService.executeQueryParam(database, sql, params);
    return result;
  }

  // ฟังก์ชันอนุมัติและตัดงบ (Transaction)
  async approveBudgetExpense(database, projectSeq, expenseList, user) {
    const client = await connection.connect(); 
    
    try {
      await client.query('BEGIN'); 

      // 2. เรียกใช้ getDTM() แทนโค้ดเดิม
      const currentDTM = getDTM(); 

      // =========================================================
      // STEP 1: คืนเงินงบประมาณเดิมก่อน (กรณีแก้ไข/ลบรายการ)
      // =========================================================
      const oldExpenses = await client.query(
          `SELECT trnbdgcod, trnexpbdg FROM ${database}.trnmst WHERE trnprjseq = $1`, 
          [projectSeq]
      );

      // วนลูปคืนเงินกลับเข้าตาราง bdgmst (bdgttl + ยอดเดิม)
      for (const oldItem of oldExpenses.rows) {
          await client.query(`
              UPDATE ${database}.bdgmst
              SET bdgttl = bdgttl + $1, bdgedtdtm = $2
              WHERE bdgcod = $3
          `, [oldItem.trnexpbdg, currentDTM, oldItem.trnbdgcod]); // update เวลาแก้ไขล่าสุด
      }

      // =========================================================
      //  STEP 2: ลบรายการเดิมทิ้ง (เพื่อเตรียมลงใหม่)
      // =========================================================
      await client.query(`DELETE FROM ${database}.trnmst WHERE trnprjseq = $1`, [projectSeq]);


      // =========================================================
      // STEP 3: บันทึกรายการใหม่ และตัดเงินใหม่
      // =========================================================
      let totalApprovedAmount = 0;

      const prjRes = await client.query(`SELECT prjnam FROM ${database}.prjmst WHERE prjseq = $1`, [projectSeq]);
      if (prjRes.rows.length === 0) throw new Error(`Project ${projectSeq} not found`);
      const projectName = prjRes.rows[0].prjnam;

      for (const expense of expenseList) {
        // 🛑 [Validation] ห้ามยอดเงินเป็น 0 หรือติดลบ
        if (!expense.amount || Number(expense.amount) <= 0) {
            return sendError(`ยอดเงินต้องมากกว่า 0 (รายการรหัสงบ: ${expense.bdgcod})`);
        }

        // [Check 2] ตรวจสอบว่ามีรหัสงบประมาณนี้จริงหรือไม่
        const checkBdgSql = `SELECT bdgseq FROM ${database}.bdgmst WHERE bdgcod = $1`;
        const checkBdgRes = await client.query(checkBdgSql, [expense.bdgcod]);
        
        if (checkBdgRes.rows.length === 0) {
            return sendError(`ไม่พบรหัสงบประมาณ: ${expense.bdgcod} ในระบบ`);
        }

        // Get Next Seq
        const seqRes = await client.query(`SELECT COALESCE(MAX(trnseq), 0) + 1 as nextseq FROM ${database}.trnmst`);
        const nextTrnSeq = seqRes.rows[0].nextseq;

        const expenseAmount = Number(expense.amount).toFixed(2);

        // Insert รายการใหม่ (บันทึก currentDTM ลง trnacpdtm)
        const sqlTrn = `
          INSERT INTO ${database}.trnmst 
          (trnseq, trnprjnam, trnprjseq, trnexpbdg, trnbdgcod, trncomstt, trnacpdtm)
          VALUES ($1, $2, $3, $4, $5, 'BAP', $6)
        `;
        await client.query(sqlTrn, [
          nextTrnSeq, 
          projectName, 
          projectSeq, 
          expenseAmount, 
          expense.bdgcod, 
          currentDTM
        ]);

        // ตัดเงินงบประมาณ (อัปเดตเวลาแก้ไข)
        const sqlUpdateBdg = `
            UPDATE ${database}.bdgmst
            SET bdgttl = bdgttl - $1, 
                bdgedtdtm = $2
            WHERE bdgcod = $3
        `;
        await client.query(sqlUpdateBdg, [expenseAmount, currentDTM, expense.bdgcod]);

        totalApprovedAmount += Number(expense.amount);
      }

      // ---------------------------------------------------------
      // STEP 4: อัปเดต Project Master (เปลี่ยนสถานะตามยอดเงิน)
      // ---------------------------------------------------------
      const formattedTotal = totalApprovedAmount.toFixed(2);

      // [UPDATED] กำหนดสถานะ: ถ้ายอดรวมเป็น 0 ให้เป็น UAC (รออนุมัติ), ถ้ามีเงินให้เป็น BAP (อนุมัติแล้ว)
      const projectStatus = totalApprovedAmount > 0 ? 'BAP' : 'UAC';

      const sqlUpdatePrj = `
        UPDATE ${database}.prjmst
        SET prjacpbdg = $1,
            prjcomstt = $2,
            prjacpdtm = $3
        WHERE prjseq = $4
      `;
      await client.query(sqlUpdatePrj, [formattedTotal, projectStatus, currentDTM, projectSeq]);

      await client.query('COMMIT'); 
      return { 
          status: true, 
          msg: 'Budget updated successfully', 
          total: formattedTotal,
          projectStatus: projectStatus 
      };

    } catch (error) {
      await client.query('ROLLBACK'); 
      console.error('Transaction Error:', error);
      throw error;
    } finally {
      client.release();
    }
  }
}