<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class AccountingReportController extends Controller
{
    /**
     * GENERATE LAPORAN LABA RUGI (INCOME STATEMENT)
     */
    public function getLabaRugi(Request $request)
    {
        try {
            $user = $request->user();
            $startDate = $request->query('start_date', Carbon::now()->startOfMonth()->toDateString());
            $endDate = $request->query('end_date', Carbon::now()->endOfMonth()->toDateString());
            
            // Proteksi Hak Akses Finansial (Security Override)
            $requestedBranchId = $request->query('branch_id', 'all');
            $branchId = ($user && $user->role !== 'owner') ? $user->branch_id : $requestedBranchId;

            // 1. QUERY BASE JURNAL
            $query = DB::table('journal_items')
                ->join('journal_entries', 'journal_items.journal_entry_id', '=', 'journal_entries.id')
                ->join('accounts', 'journal_items.account_id', '=', 'accounts.id')
                ->whereBetween('journal_entries.entry_date', [$startDate, $endDate])
                ->whereIn('accounts.group', ['revenue', 'expense']);

            if ($branchId !== 'all' && !empty($branchId)) {
                $query->where('journal_entries.branch_id', $branchId);
            }

            // 2. REKAP SALDO PER AKUN
            $balances = $query->select(
                    'accounts.id',
                    'accounts.code as account_code',
                    'accounts.name as account_name',
                    'accounts.group as account_type',
                    DB::raw('SUM(journal_items.debit) as total_debit'),
                    DB::raw('SUM(journal_items.credit) as total_credit')
                )
                ->groupBy(
                    'accounts.id', 
                    'accounts.code', 
                    'accounts.name', 
                    'accounts.group'
                )
                ->orderBy('accounts.code', 'asc')
                ->get();

            // 3. KELOMPOKKAN BERDASARKAN TIPE DAN KODE AKUN
            $revenues = [];
            $cogs = [];
            $expenses = [];
            $otherRevenues = [];
            $otherExpenses = [];

            $totalRevenue = 0;
            $totalCogs = 0;
            $totalExpense = 0;
            $totalOtherRevenue = 0;
            $totalOtherExpense = 0;

            foreach ($balances as $acc) {
                $normal_balance = in_array($acc->account_type, ['asset', 'expense']) ? 'debit' : 'credit';

                $net = 0;
                if ($normal_balance === 'debit') {
                    $net = $acc->total_debit - $acc->total_credit;
                } else {
                    $net = $acc->total_credit - $acc->total_debit;
                }

                if ($net != 0) {
                    $item = [
                        'code' => $acc->account_code,
                        'name' => $acc->account_name,
                        'balance' => $net
                    ];

                    // PERBAIKAN FATAL: Disesuaikan persis dengan struktur awalan `accounts.sql` Anda
                    $prefix2 = substr($acc->account_code, 0, 2);

                    if ($acc->account_type === 'revenue') {
                        if ($prefix2 == '71') { 
                            // 71xx = PENDAPATAN DILUAR USAHA
                            $otherRevenues[] = $item;
                            $totalOtherRevenue += $net;
                        } else {
                            // 40xx = PENDAPATAN USAHA UTAMA
                            $revenues[] = $item; 
                            $totalRevenue += $net;
                        }
                    } elseif ($acc->account_type === 'expense') {
                        if ($prefix2 == '50') { 
                            // 50xx = HPP
                            $cogs[] = $item;
                            $totalCogs += $net;
                        } elseif ($prefix2 == '72') { 
                            // 72xx = BIAYA LAIN-LAIN (Diluar Usaha)
                            $otherExpenses[] = $item;
                            $totalOtherExpense += $net;
                        } else { 
                            // 61xx, 62xx = BIAYA OPERASIONAL
                            $expenses[] = $item;
                            $totalExpense += $net;
                        }
                    }
                }
            }

            // 4. HITUNG HIERARKI LABA
            $grossProfit = $totalRevenue - $totalCogs;
            $operatingProfit = $grossProfit - $totalExpense;
            $netProfit = $operatingProfit + $totalOtherRevenue - $totalOtherExpense;

            return response()->json([
                'success' => true,
                'period' => [
                    'start' => $startDate, 
                    'end' => $endDate
                ],
                'data' => [
                    'revenues' => $revenues,
                    'cogs' => $cogs,
                    'expenses' => $expenses,
                    'other_revenues' => $otherRevenues,
                    'other_expenses' => $otherExpenses,
                    'totals' => [
                        'total_revenue' => $totalRevenue,
                        'total_cogs' => $totalCogs,
                        'gross_profit' => $grossProfit,
                        'total_expense' => $totalExpense,
                        'operating_profit' => $operatingProfit,
                        'total_other_revenue' => $totalOtherRevenue,
                        'total_other_expense' => $totalOtherExpense,
                        'net_profit' => $netProfit
                    ]
                ]
            ]);

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

    /**
     * ========================================================
     * 2. GENERATE LAPORAN NERACA (BALANCE SHEET)
     * ========================================================
     */
    public function getNeraca(Request $request)
    {
        try {
            $user = $request->user();
            $endDate = $request->query('end_date', Carbon::now()->toDateString());
            
            // Proteksi Hak Akses Finansial
            $requestedBranchId = $request->query('branch_id', 'all');
            $branchId = ($user && $user->role !== 'owner') ? $user->branch_id : $requestedBranchId;

            // QUERY JURNAL SAMPAI DENGAN TANGGAL END_DATE
            $query = DB::table('journal_items')
                ->join('journal_entries', 'journal_items.journal_entry_id', '=', 'journal_entries.id')
                ->join('accounts', 'journal_items.account_id', '=', 'accounts.id')
                ->where('journal_entries.entry_date', '<=', $endDate);

            if ($branchId !== 'all' && !empty($branchId)) {
                $query->where('journal_entries.branch_id', $branchId);
            }

            // PERBAIKAN VALIDASI AUDIT: Tarik ID akun yang secara resmi di-mapping untuk cabang ini
            $mappedAccountIds = [];
            if ($branchId !== 'all' && !empty($branchId)) {
                $mappedAccountIds = DB::table('branch_accounts')
                    ->where('branch_id', $branchId)
                    ->pluck('account_id')
                    ->toArray();
            }

            // REKAP SALDO PER AKUN
            $balances = $query->select(
                    'accounts.id',
                    'accounts.code as account_code',
                    'accounts.name as account_name',
                    'accounts.group as account_type',
                    DB::raw('SUM(journal_items.debit) as total_debit'),
                    DB::raw('SUM(journal_items.credit) as total_credit')
                )
                ->groupBy(
                    'accounts.id', 
                    'accounts.code', 
                    'accounts.name', 
                    'accounts.group'
                )
                ->orderBy('accounts.code', 'asc')
                ->get();

            $assets = [];
            $liabilities = [];
            $equities = [];
            
            $totalAsset = 0;
            $totalLiability = 0;
            $totalEquity = 0;
            
            $labaBerjalan = 0;

            foreach ($balances as $acc) {
                $normal_balance = in_array($acc->account_type, ['asset', 'expense']) ? 'debit' : 'credit';
                
                $net = 0;
                if ($normal_balance === 'debit') {
                    $net = $acc->total_debit - $acc->total_credit;
                } else {
                    $net = $acc->total_credit - $acc->total_debit;
                }

                if ($net != 0) {
                    $item = [
                        'code' => $acc->account_code,
                        'name' => $acc->account_name,
                        'balance' => $net
                    ];

                    if ($acc->account_type === 'asset') {
                        // VALIDASI BACKEND: Beri tanda pada Assets apakah rekening ini resmi mapping cabang 
                        // Membantu auditor melacak jika ada saldo di Bank yang salah input
                        if ($branchId !== 'all' && !empty($branchId)) {
                            // Cek jika akun berawalan 10 (Kas/Bank), berikan tag mapping
                            $prefix = substr($acc->account_code, 0, 2);
                            if ($prefix == '10') {
                                $item['is_mapped_bank'] = in_array($acc->id, $mappedAccountIds);
                            }
                        }
                        
                        $assets[] = $item;
                        $totalAsset += $net;
                    } elseif ($acc->account_type === 'liability') {
                        $liabilities[] = $item;
                        $totalLiability += $net;
                    } elseif ($acc->account_type === 'equity') {
                        $equities[] = $item;
                        $totalEquity += $net;
                    } elseif ($acc->account_type === 'revenue') {
                        $labaBerjalan += $net;
                    } elseif ($acc->account_type === 'expense') {
                        $labaBerjalan -= $net;
                    }
                }
            }

            // INJEKSI LABA TAHUN BERJALAN KE DALAM EKUITAS
            if ($labaBerjalan != 0) {
                $equities[] = [
                    'code' => '3999', 
                    'name' => 'Laba Tahun Berjalan (Current Earnings)',
                    'balance' => $labaBerjalan
                ];
                $totalEquity += $labaBerjalan;
            }

            $totalLiabilityAndEquity = $totalLiability + $totalEquity;

            return response()->json([
                'success' => true,
                'period' => [
                    'as_of' => $endDate
                ],
                'data' => [
                    'assets' => $assets,
                    'liabilities' => $liabilities,
                    'equities' => $equities,
                    'totals' => [
                        'total_asset' => $totalAsset,
                        'total_liability' => $totalLiability,
                        'total_equity' => $totalEquity,
                        'total_liability_equity' => $totalLiabilityAndEquity
                    ],
                    // Validasi Keseimbangan
                    'is_balanced' => round($totalAsset, 2) === round($totalLiabilityAndEquity, 2)
                ]
            ]);

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