<?php

namespace App\Http\Controllers\Api;

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

class AccountingJournalApiController extends Controller
{
    /**
     * Tampilkan Daftar Jurnal (Buku Besar / Riwayat Jurnal)
     */
    public function index(Request $request)
    {
        try {
            $user = $request->user();
            
            // Query mengambil Header Jurnal beserta Detailnya
            $query = DB::table('journal_entries as h')
                ->join('journal_items as d', 'h.id', '=', 'd.journal_entry_id')
                ->join('accounts as a', 'd.account_id', '=', 'a.id')
                ->select(
                    'h.id',
                    'h.entry_date as transaction_date', 
                    'h.description',
                    'h.source_type as reference_type',  
                    'h.reference as reference_id',      
                    'a.code as account_code',
                    'a.name as account_name',
                    'd.debit',
                    'd.credit'
                );

            // =========================================================================
            // PERBAIKAN ENTERPRISE: Isolasi Cabang Buku Besar
            // =========================================================================
            if ($user && !in_array($user->role, ['owner', 'super_admin'])) {
                // 1. Admin Cabang: Terkunci mutlak di cabangnya sendiri
                $query->where('h.branch_id', $user->branch_id);
            } 
            elseif ($request->filled('branch_id') && $request->branch_id !== 'all') {
                // 2. Owner / Super Admin: Bisa memfilter berdasarkan dropdown cabang dari UI
                $query->where('h.branch_id', $request->branch_id);
            }
            // =========================================================================

            // Filter Pencarian Teks (Keterangan / Referensi / Nama Akun)
            if ($request->filled('search')) {
                $search = $request->search;
                $query->where(function($q) use ($search) {
                    $q->where('h.description', 'like', "%{$search}%")
                      ->orWhere('h.reference', 'like', "%{$search}%")
                      ->orWhere('h.source_type', 'like', "%{$search}%")
                      ->orWhere('a.name', 'like', "%{$search}%")
                      ->orWhere('a.code', 'like', "%{$search}%");
                });
            }

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

            $journals = $query->orderBy('h.entry_date', 'desc')
                              ->orderBy('h.id', 'desc')
                              ->get();

            // Mengelompokkan berdasarkan Header ID
            $grouped = $journals->groupBy('id')->values();

            // Mapping ulang koleksi agar menjadi format JSON bercabang (Nested Array) yang sangat rapi untuk dibaca Next.js
            $formattedData = $grouped->map(function ($items) {
                $header = $items->first();
                
                return [
                    'id'               => $header->id,
                    'transaction_date' => $header->transaction_date,
                    'description'      => $header->description,
                    'reference_type'   => $header->reference_type,
                    'reference_id'     => $header->reference_id,
                    'items'            => $items->map(function ($item) {
                        return [
                            'account_code' => $item->account_code,
                            'account_name' => $item->account_name,
                            'debit'        => (float) $item->debit,
                            'credit'       => (float) $item->credit,
                        ];
                    })->values()->toArray(),
                    'total_debit'      => $items->sum('debit'),
                    'total_credit'     => $items->sum('credit')
                ];
            });

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

    /**
     * Input Jurnal Umum / Manual (Memorial)
     */
    public function store(Request $request)
    {
        $request->validate([
            'entry_date' => 'required|date',
            'description' => 'required|string|max:255',
            'items' => 'required|array|min:2', // Minimal 2 baris (Debit & Kredit)
            'items.*.account_id' => 'required|exists:accounts,id',
            'items.*.debit' => 'required|numeric|min:0',
            'items.*.credit' => 'required|numeric|min:0',
            'branch_id' => 'nullable|exists:branches,id'
        ]);

        $user = $request->user();
        
        // PERBAIKAN: Izinkan Super Admin untuk mendefinisikan branch_id
        $branchId = ($user && in_array($user->role, ['owner', 'super_admin']) && $request->filled('branch_id')) 
                    ? $request->branch_id 
                    : ($user->branch_id ?? 1);

        DB::beginTransaction();
        try {
            // PERBAIKAN: Validasi Isolasi Rekening Cabang (Bypass Super Admin)
            if ($user && !in_array($user->role, ['owner', 'super_admin'])) {
                $otherBranchesAccountIds = DB::table('branch_accounts')
                    ->where('branch_id', '!=', $user->branch_id)
                    ->pluck('account_id')
                    ->toArray();

                $submittedAccountIds = array_column($request->items, 'account_id');
                
                if (!empty(array_intersect($submittedAccountIds, $otherBranchesAccountIds))) {
                    throw new \Exception("Akses ditolak: Anda tidak diizinkan membuat jurnal manual menggunakan rekening Bank/Kas yang dipetakan untuk cabang lain.");
                }
            }

            // 1. Validasi Keseimbangan (Double-Entry Checking)
            $totalDebit = 0;
            $totalCredit = 0;

            foreach ($request->items as $item) {
                $totalDebit += (float) $item['debit'];
                $totalCredit += (float) $item['credit'];
            }

            if (round($totalDebit, 2) !== round($totalCredit, 2)) {
                throw new \Exception("Jurnal tidak seimbang! Total Debit (Rp " . number_format($totalDebit, 2) . ") tidak sama dengan Total Kredit (Rp " . number_format($totalCredit, 2) . ").");
            }

            if ($totalDebit <= 0) {
                throw new \Exception("Total jurnal tidak boleh nol.");
            }

            // 2. Simpan Header Jurnal
            $headerId = DB::table('journal_entries')->insertGetId([
                'branch_id'   => $branchId,
                'entry_date'  => $request->entry_date,
                'description' => $request->description,
                'source_type' => 'JURNAL_UMUM',
                'reference'   => 'JU-' . date('ymd') . '-' . mt_rand(1000, 9999),
                'user_id'     => $user->id ?? 1,
                'created_at'  => Carbon::now(),
                'updated_at'  => Carbon::now(),
            ]);

            // 3. Simpan Detail Jurnal
            $insertItems = [];
            foreach ($request->items as $item) {
                if ((float)$item['debit'] > 0 || (float)$item['credit'] > 0) {
                    $insertItems[] = [
                        'journal_entry_id' => $headerId,
                        'account_id'       => $item['account_id'],
                        'debit'            => (float) $item['debit'],
                        'credit'           => (float) $item['credit'],
                        'created_at'       => Carbon::now(),
                        'updated_at'       => Carbon::now(),
                    ];
                }
            }

            DB::table('journal_items')->insert($insertItems);

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

    /**
     * Hapus / Void Jurnal Manual
     */
    public function destroy(Request $request, $id)
    {
        DB::beginTransaction();
        try {
            $user = $request->user();
            $journal = DB::table('journal_entries')->where('id', $id)->first();

            if (!$journal) {
                return response()->json(['success' => false, 'message' => 'Data jurnal tidak ditemukan.'], 404);
            }

            // PERBAIKAN: Proteksi Hak Akses Cabang (Bypass Super Admin)
            if ($user && !in_array($user->role, ['owner', 'super_admin']) && $journal->branch_id !== $user->branch_id) {
                throw new \Exception('Akses ditolak: Anda tidak memiliki hak akses untuk menghapus jurnal cabang lain.');
            }

            // PROTEKSI KRITIKAL ENTERPRISE
            if ($journal->source_type !== 'JURNAL_UMUM') {
                throw new \Exception('Ditolak: Anda tidak dapat menghapus Jurnal Sistem Otomatis (' . $journal->source_type . ') secara langsung. Silakan hapus transaksi asalnya.');
            }

            DB::table('journal_items')->where('journal_entry_id', $id)->delete();
            DB::table('journal_entries')->where('id', $id)->delete();

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