<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\PayrollPeriod;
use App\Models\Payroll;
use App\Services\AccountingService;
use Carbon\Carbon;

class FinancePayrollController extends Controller
{
    /**
     * Mengeksekusi pencairan dana gaji dan membentuk Jurnal Kas Keluar (Disbursement)
     */
    public function pay(Request $request, $id)
    {
        // Validasi input dari Frontend
        $request->validate([
            'payment_account_id' => 'required|exists:accounts,id',
            'payment_date'       => 'required|date',
            'reference_note'     => 'nullable|string'
        ]);

        DB::beginTransaction();
        try {
            // Mengunci baris data di database untuk mencegah pencairan ganda (Double-spend)
            $period = PayrollPeriod::lockForUpdate()->findOrFail($id);

            // Validasi Status: Hanya periode yang berstatus 'approved' yang boleh dicairkan
            if ($period->status !== 'approved') {
                throw new \Exception("Sistem Keamanan: Periode ini berstatus '{$period->status}'. Hanya periode berstatus 'approved' (sudah di-posting HRD) yang dapat dibayar.");
            }

            // Tarik seluruh slip gaji (payrolls) yang belum dibayar pada periode ini
            $payrolls = DB::table('payrolls')
                ->join('employees', 'payrolls.employee_id', '=', 'employees.id')
                ->leftJoin('positions', 'employees.position_id', '=', 'positions.id')
                ->select('payrolls.*', 'positions.expense_group')
                ->where('payrolls.payroll_period_id', $period->id)
                ->where('payrolls.payment_status', 'unpaid')
                ->get();

            if ($payrolls->isEmpty()) {
                throw new \Exception("Tidak ada tagihan gaji yang perlu dibayar pada periode ini.");
            }

            // Tarik Pemetaan Master Akun (COA) untuk Hutang Gaji
            $akunHutangGajiOpex = AccountingService::getAccountId('payable_salary_account') ?? 
                                  DB::table('accounts')->where('name', 'like', '%Hutang Gaji%')->value('id'); 
                                  
            $akunHutangUpahHpp  = AccountingService::getAccountId('payable_btkl_account') ?? 
                                  DB::table('accounts')->where('code', '2110')->value('id'); 

            if (!$akunHutangGajiOpex || !$akunHutangUpahHpp) {
                throw new \Exception("Sistem Gagal: Pemetaan Master Akun untuk Hutang Gaji/Upah belum lengkap.");
            }

            // Kalkulasi Agregat: Pisahkan hutang pabrik (HPP) dan hutang staf (OPEX) agar jurnal akurat
            $totalHutangOpex = 0;
            $totalHutangHpp  = 0;

            foreach ($payrolls as $payroll) {
                if ($payroll->expense_group === 'hpp') {
                    $totalHutangHpp += $payroll->net_salary;
                } else {
                    $totalHutangOpex += $payroll->net_salary;
                }
            }

            $totalPayment = $totalHutangOpex + $totalHutangHpp;

            // =================================================================
            // A. AUTO-ROUTING JURNAL PENGELUARAN KAS (DISBURSEMENT)
            // =================================================================
            $journalItems = [];

            // DEBIT: Pelunasan Hutang Gaji Staf (Kewajiban Berkurang)
            if ($totalHutangOpex > 0) {
                $journalItems[] = ['account_id' => $akunHutangGajiOpex, 'debit' => $totalHutangOpex, 'credit' => 0];
            }

            // DEBIT: Pelunasan Hutang Upah Pabrik (Kewajiban Berkurang)
            if ($totalHutangHpp > 0) {
                $journalItems[] = ['account_id' => $akunHutangUpahHpp, 'debit' => $totalHutangHpp, 'credit' => 0];
            }

            // KREDIT: Pemotongan Kas / Bank (Aset Berkurang)
            $journalItems[] = [
                'account_id' => $request->payment_account_id, 
                'debit'      => 0, 
                'credit'     => $totalPayment
            ];

            $note = $request->reference_note ?: "Pencairan Gaji Periode " . $period->period_name;

            // Kirim transaksi ke Core Accounting Engine Service
            AccountingService::log([
                'branch_id'   => $period->branch_id ?? 1,
                'entry_date'  => $request->payment_date,
                'description' => $note,
                'reference'   => 'PAYOUT-' . $period->year . str_pad($period->month, 2, '0', STR_PAD_LEFT),
                'source_type' => 'PAYROLL_DISBURSEMENT',
                'user_id'     => $request->user()->id ?? 1,
                'items'       => $journalItems
            ]);

            // =================================================================
            // B. UPDATE STATUS SLIP GAJI & PERIODE MENJADI LUNAS (PAID)
            // =================================================================
            DB::table('payrolls')
                ->where('payroll_period_id', $period->id)
                ->where('payment_status', 'unpaid')
                ->update([
                    'payment_status'     => 'paid',
                    'payment_date'       => $request->payment_date,
                    'payment_account_id' => $request->payment_account_id,
                    'updated_at'         => Carbon::now()
                ]);

            $period->update([
                'status' => 'paid'
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Pencairan Gaji Berhasil Dieksekusi! Jurnal Pengeluaran Kas (Disbursement) telah dicatat ke Buku Besar.'
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }
}