<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\CashMutation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\AccountingService;

class CashMutationApiController extends Controller
{
    public function index(Request $request)
    {
        try {
            $user = $request->user();
            
            if (!$user) {
                return response()->json(['success' => false, 'message' => 'Sesi habis atau tidak valid'], 401);
            }

            $query = CashMutation::with(['fromAccount', 'toAccount'])
                ->orderBy('mutation_date', 'desc')
                ->orderBy('id', 'desc');

            // 1. Filter Cabang Otomatis (STRICT ENTERPRISE: Berlaku untuk SEMUA ROLE termasuk Owner)
            $query->where('branch_id', $user->branch_id);

            // 2. Filter Pencarian Teks (Catatan/Note)
            if ($request->filled('search')) {
                $query->where('note', 'like', "%{$request->search}%");
            }

            // 3. Filter Rentang Tanggal
            if ($request->filled('start_date')) {
                $query->whereDate('mutation_date', '>=', $request->start_date);
            }
            if ($request->filled('end_date')) {
                $query->whereDate('mutation_date', '<=', $request->end_date);
            }

            // 4. Filter Tipe Mutasi
            if ($request->filled('type') && $request->type !== 'all') {
                $query->where('type', $request->type);
            }

            // 5. Filter Akun Kas (Mencari di Akun Asal atau Akun Tujuan)
            if ($request->filled('account_id') && $request->account_id !== 'all') {
                $query->where(function($q) use ($request) {
                    $q->where('from_account_id', $request->account_id)
                      ->orWhere('to_account_id', $request->account_id);
                });
            }

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

    public function store(Request $request)
    {
        $request->validate([
            'mutation_date' => 'required|date',
            'type' => 'required|in:transfer,opening_balance,reimbursement,transfer_pusat,terima_pusat',
            'from_account_id' => 'required_if:type,transfer,reimbursement,transfer_pusat,terima_pusat|nullable|exists:accounts,id',
            'to_account_id' => 'required|exists:accounts,id',
            'amount' => 'required|numeric|min:1',
            'note' => 'nullable|string',
        ]);

        DB::beginTransaction();
        try {
            $user = $request->user();
            
            // PENAMBAHAN: Validasi Kepemilikan Rekening (Security Lock)
            // STRICT ENTERPRISE: Memastikan SEMUA PENGGUNA (termasuk Owner) tidak salah/membajak ID akun cabang lain
            if ($user) {
                $myBranchId = $user->branch_id;
                
                // =========================================================================
                // PERBAIKAN ENTERPRISE: Strict Mapping Validation (Tanpa Fallback Bypass)
                // =========================================================================
                $checkAccountAuth = function($accountId) use ($myBranchId) {
                    if (!$accountId) return true; // Untuk opening_balance (from_account_id bisa null)

                    return DB::table('branch_accounts')
                        ->where('branch_id', $myBranchId)
                        ->where('account_id', $accountId)
                        ->where('is_active', 1) // Pastikan mapping berstatus aktif
                        ->exists();
                };
                // =========================================================================

                // Terapkan aturan berdasarkan tipe mutasi
                if (in_array($request->type, ['transfer', 'reimbursement'])) {
                    if (!$checkAccountAuth($request->from_account_id) || !$checkAccountAuth($request->to_account_id)) {
                        throw new \Exception('Akses ditolak (Security Lock): Akun asal atau tujuan mutasi belum dipetakan untuk wewenang cabang Anda. Silakan ganti konteks cabang atau hubungi Pusat.');
                    }
                } elseif (in_array($request->type, ['opening_balance', 'terima_pusat'])) {
                    if (!$checkAccountAuth($request->to_account_id)) {
                        throw new \Exception('Akses ditolak (Security Lock): Akun penerima dana belum dipetakan untuk wewenang cabang Anda. Silakan ganti konteks cabang atau hubungi Pusat.');
                    }
                } elseif ($request->type === 'transfer_pusat') {
                    if (!$checkAccountAuth($request->from_account_id)) {
                        throw new \Exception('Akses ditolak (Security Lock): Akun asal sumber dana belum dipetakan untuk wewenang cabang Anda. Silakan ganti konteks cabang atau hubungi Pusat.');
                    }
                }
            }

            // 1. Simpan Transaksi Mutasi
            $mutation = CashMutation::create([
                'mutation_date' => $request->mutation_date,
                'from_account_id' => $request->from_account_id,
                'to_account_id' => $request->to_account_id,
                'amount' => $request->amount,
                'type' => $request->type,
                'note' => $request->note,
                'branch_id' => $user->branch_id ?? 1, 
                'user_id' => $user->id,
            ]);

            // 2. LOGIKA JURNAL OTOMATIS (Disempurnakan untuk Enterprise GL & Rekening Koran)
            $type = $request->type;
            
            // JURNAL GANDA (DUAL JOURNALING) UNTUK TRANSAKSI LINTAS ENTITAS (PUSAT - CABANG)
            if ($type === 'transfer_pusat' || $type === 'terima_pusat') {
                
                // Cari ID Akun R/K. Fallback menggunakan pencarian LIKE jika belum ada di setting.
                $rkPusatId = AccountingService::getAccountId('rk_pusat_account') 
                             ?? DB::table('accounts')->where('name', 'like', '%R/K Pusat%')->value('id');
                
                $rkCabangId = AccountingService::getAccountId('rk_cabang_account_' . ($user->branch_id ?? 1)) 
                              ?? DB::table('accounts')->where('name', 'like', '%R/K Cabang%')->value('id');

                if (!$rkPusatId || !$rkCabangId) {
                    throw new \Exception("Akun R/K (Rekening Koran) Antar Kantor belum disetting di master akun. Harap buat akun R/K terlebih dahulu.");
                }

                if ($type === 'transfer_pusat') {
                    // Setor ke Pusat
                    // Jurnal Buku Cabang
                    AccountingService::log([
                        'branch_id'   => $user->branch_id ?? 1,
                        'entry_date'  => $request->mutation_date,
                        'description' => "Setoran Dana ke Pusat: " . ($request->note ?? 'Perpindahan Dana'),
                        'reference'   => "MUT-OUT-" . str_pad($mutation->id, 5, '0', STR_PAD_LEFT),
                        'source_type' => 'CASH_MUTATION_RK',
                        'user_id'     => $user->id,
                        'items' => [
                            ['account_id' => $rkPusatId, 'debit' => $request->amount, 'credit' => 0],
                            ['account_id' => $request->from_account_id, 'debit' => 0, 'credit' => $request->amount]
                        ]
                    ]);

                    // Jurnal Buku Pusat (Asumsi Pusat menggunakan branch_id = 0 atau ID Pusat spesifik)
                    AccountingService::log([
                        'branch_id'   => 0, // Anda bisa ubah ini ke ID Cabang Pusat di tabel cabang Anda jika berbeda
                        'entry_date'  => $request->mutation_date,
                        'description' => "Terima Setoran dari Cabang: " . ($request->note ?? 'Perpindahan Dana'),
                        'reference'   => "MUT-IN-" . str_pad($mutation->id, 5, '0', STR_PAD_LEFT),
                        'source_type' => 'CASH_MUTATION_RK',
                        'user_id'     => $user->id,
                        'items' => [
                            ['account_id' => $request->to_account_id, 'debit' => $request->amount, 'credit' => 0],
                            ['account_id' => $rkCabangId, 'debit' => 0, 'credit' => $request->amount]
                        ]
                    ]);

                } else {
                    // Terima dari Pusat (Misal: Drop Dana Kas Kecil)
                    // Jurnal Buku Cabang
                    AccountingService::log([
                        'branch_id'   => $user->branch_id ?? 1,
                        'entry_date'  => $request->mutation_date,
                        'description' => "Terima Dana dari Pusat: " . ($request->note ?? 'Drop Dana Operasional'),
                        'reference'   => "MUT-IN-" . str_pad($mutation->id, 5, '0', STR_PAD_LEFT),
                        'source_type' => 'CASH_MUTATION_RK',
                        'user_id'     => $user->id,
                        'items' => [
                            ['account_id' => $request->to_account_id, 'debit' => $request->amount, 'credit' => 0],
                            ['account_id' => $rkPusatId, 'debit' => 0, 'credit' => $request->amount]
                        ]
                    ]);

                    // Jurnal Buku Pusat
                    AccountingService::log([
                        'branch_id'   => 0,
                        'entry_date'  => $request->mutation_date,
                        'description' => "Drop Dana ke Cabang: " . ($request->note ?? 'Drop Dana Operasional'),
                        'reference'   => "MUT-OUT-" . str_pad($mutation->id, 5, '0', STR_PAD_LEFT),
                        'source_type' => 'CASH_MUTATION_RK',
                        'user_id'     => $user->id,
                        'items' => [
                            ['account_id' => $rkCabangId, 'debit' => $request->amount, 'credit' => 0],
                            ['account_id' => $request->from_account_id, 'debit' => 0, 'credit' => $request->amount]
                        ]
                    ]);
                }

            } else {
                // JURNAL TUNGGAL UNTUK TRANSAKSI INTERNAL CABANG (YANG SUDAH ADA SEBELUMNYA)
                $debitAccountId = $request->to_account_id;
                $creditAccountId = null;
                $journalDescription = '';

                if ($request->type === 'opening_balance') {
                    // Prioritaskan setting, jika kosong cari akun Modal (Equity) pertama sebagai fallback aman
                    $creditAccountId = AccountingService::getAccountId('default_migration_equity_account') 
                                       ?? DB::table('accounts')->where('group', 'equity')->value('id');
                    $journalDescription = "Saldo Awal Kas/Bank: " . ($request->note ?? 'Setoran Modal');
                    
                } elseif ($request->type === 'reimbursement') {
                    $creditAccountId = $request->from_account_id;
                    $journalDescription = "Reimbursement Kas/Bank: " . ($request->note ?? 'Pengisian Ulang Dana');
                    
                } else { // Transfer antar kas/bank internal
                    $creditAccountId = $request->from_account_id;
                    $journalDescription = "Mutasi Transfer: " . ($request->note ?? 'Perpindahan Dana Internal');
                }

                // Validasi akhir sebelum melempar ke AccountingService untuk mencegah null exception
                if (!$creditAccountId) {
                    throw new \Exception("Akun kredit tidak ditemukan. Pastikan akun asal dipilih atau akun Modal (Equity) tersedia di master akun.");
                }

                if ($debitAccountId && $creditAccountId) {
                    AccountingService::log([
                        'branch_id'   => $user->branch_id ?? 1,
                        'entry_date'  => $request->mutation_date,
                        'description' => $journalDescription,
                        'reference'   => "MUT-" . str_pad($mutation->id, 5, '0', STR_PAD_LEFT),
                        'source_type' => 'CASH_MUTATION',
                        'user_id'     => $user->id, // Audit trail eksplisit
                        'items' => [
                            ['account_id' => $debitAccountId, 'debit' => $request->amount, 'credit' => 0],
                            ['account_id' => $creditAccountId, 'debit' => 0, 'credit' => $request->amount]
                        ]
                    ]);
                }
            }

            DB::commit();
            return response()->json(['success' => true, 'message' => 'Mutasi berhasil dicatat & dijurnal!']);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }
}