<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Sale;
use App\Models\Customer;
use App\Models\Branch;
use App\Services\AccountingService; 
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class MigrationCustomerDebtApiController extends Controller
{
    // --- 1. AMBIL DATA PIUTANG AWAL (FULL LIST) ---
    public function index(Request $request)
    {
        try {
            $user = $request->user();
            
            $query = Sale::with(['customer.district.city', 'branch'])
                ->where('is_initial_debt', true);

            // PERBAIKAN ENTERPRISE: Isolasi Data Cabang
            if ($user && $user->role !== 'owner') {
                $query->where('branch_id', $user->branch_id);
            }

            $data = $query->orderBy('created_at', 'desc')
                ->get()
                ->map(function($item) {
                    return [
                        'id' => $item->id,
                        'customer_id' => $item->customer_id,
                        'customer_name' => $item->customer_name,
                        'customer_code' => $item->customer?->customer_code,
                        'address' => $item->customer?->address,
                        'city' => $item->customer?->district?->city?->name,
                        'invoice_number' => $item->invoice_number,
                        'grand_total' => $item->grand_total,
                        'created_at' => $item->created_at,
                        'due_date' => $item->due_date,
                        'branch' => $item->branch,
                    ];
                });

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

    // --- 2. AMBIL DATA PELANGGAN (FULL DATA UNTUK DROPDOWN) ---
    public function getCustomers(Request $request)
    {
        try {
            $user = $request->user();

            $query = Customer::with('branch')
                ->where('is_active', true);

            // PERBAIKAN ENTERPRISE: Isolasi Dropdown Cabang
            if ($user && $user->role !== 'owner') {
                $query->where('branch_id', $user->branch_id);
            }

            $customers = $query->orderBy('name', 'asc')->get();

            return response()->json([
                'success' => true, 
                'data' => $customers
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false, 
                'message' => 'Gagal memuat list pelanggan: ' . $e->getMessage()
            ], 500);
        }
    }

    // --- 3. INPUT MANUAL (UTUH & VALIDASI KETAT) ---
    public function storeManual(Request $request)
    {
        $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'invoice_number' => 'required|string|unique:sales,invoice_number',
            'grand_total' => 'required|numeric|min:1',
            'created_at' => 'required|date',
            'due_date' => 'required|date',
        ]);

        $user = $request->user();
        $customer = Customer::find($request->customer_id);
        
        // PERBAIKAN ENTERPRISE: Proteksi Manipulasi Pelanggan Lintas Cabang (API Tampering)
        if (!$customer || ($user && $user->role !== 'owner' && $customer->branch_id !== $user->branch_id)) {
            return response()->json(['success' => false, 'message' => 'Data pelanggan tidak valid atau bukan dari wilayah cabang Anda.'], 403);
        }

        DB::beginTransaction();
        try {
            $sale = new Sale();
            $sale->branch_id = $customer->branch_id; 
            $sale->user_id = $user->id;
            $sale->customer_id = $customer->id;
            $sale->customer_name = $customer->name;
            $sale->invoice_number = $request->invoice_number;
            $sale->subtotal = $request->grand_total;
            $sale->grand_total = $request->grand_total;
            $sale->discount_amount = 0;
            $sale->tax_amount = 0;
            $sale->payment_method = 'kredit';
            $sale->payment_status = 'pending';
            $sale->is_initial_debt = true;
            $sale->created_at = Carbon::parse($request->created_at);
            $sale->updated_at = Carbon::now();
            $sale->due_date = Carbon::parse($request->due_date);
            $sale->save();

            // ----------------------------------------------------------------
            // JURNAL AKUNTANSI: SALDO AWAL PIUTANG (MANUAL) DENGAN STRICT VALIDATION
            // ----------------------------------------------------------------
            $receivableAcc = AccountingService::getAccountId('default_receivable_account');
            $equityAcc     = AccountingService::getAccountId('default_migration_equity_account');

            if (!$receivableAcc || !$equityAcc) {
                throw new \Exception("Sistem Gagal: Akun Piutang atau Akun Modal untuk migrasi belum dikonfigurasi di Master Akun Global. Hubungi Pusat.");
            }

            AccountingService::log([
                'branch_id'   => $customer->branch_id,
                'entry_date'  => Carbon::parse($request->created_at)->toDateString(),
                'description' => "Saldo Awal Piutang: " . $customer->name,
                'reference'   => $request->invoice_number,
                'source_type' => 'migration_receivable',
                'user_id'     => $user->id,
                'items' => [
                    ['account_id' => $receivableAcc, 'debit' => $request->grand_total, 'credit' => 0],
                    ['account_id' => $equityAcc, 'debit' => 0, 'credit' => $request->grand_total],
                ]
            ]);
            // ----------------------------------------------------------------

            DB::commit();
            return response()->json([
                'success' => true, 
                'message' => 'Saldo awal piutang pelanggan berhasil dicatat!'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false, 
                'message' => 'Terjadi kesalahan sistem: ' . $e->getMessage()
            ], 500);
        }
    }

    // --- 4. UPDATE DATA (DENGAN SINKRONISASI JURNAL) ---
    public function update(Request $request, $id)
    {
        $request->validate([
            'invoice_number' => 'required|string|unique:sales,invoice_number,' . $id,
            'grand_total' => 'required|numeric|min:1',
            'created_at' => 'required|date',
            'due_date' => 'required|date',
        ]);

        $user = $request->user();

        DB::beginTransaction();
        try {
            $sale = Sale::where('is_initial_debt', true)->findOrFail($id);

            // PERBAIKAN ENTERPRISE: Proteksi Update Silang Cabang
            if ($user && $user->role !== 'owner' && $sale->branch_id !== $user->branch_id) {
                return response()->json(['success' => false, 'message' => 'Akses ditolak: Data piutang ini bukan wewenang cabang Anda.'], 403);
            }

            $oldInvoiceNumber = $sale->invoice_number; 
            
            $sale->invoice_number = $request->invoice_number;
            $sale->subtotal = $request->grand_total;
            $sale->grand_total = $request->grand_total;
            $sale->created_at = Carbon::parse($request->created_at);
            $sale->due_date = Carbon::parse($request->due_date);
            $sale->save();

            // ----------------------------------------------------------------
            // UPDATE JURNAL: Agar Buku Besar Tetap Balance
            // ----------------------------------------------------------------
            $journal = \App\Models\JournalEntry::where('reference', $oldInvoiceNumber)
                ->where('source_type', 'migration_receivable')
                ->first();

            if ($journal) {
                $journal->update([
                    'reference' => $request->invoice_number,
                    'entry_date' => Carbon::parse($request->created_at)
                ]);

                $receivableAcc = AccountingService::getAccountId('default_receivable_account');
                $equityAcc     = AccountingService::getAccountId('default_migration_equity_account');

                if (!$receivableAcc || !$equityAcc) {
                    throw new \Exception("Sistem Gagal: Konfigurasi Master Akun telah dihapus.");
                }

                \App\Models\JournalItem::where('journal_entry_id', $journal->id)
                    ->where('account_id', $receivableAcc)
                    ->update(['debit' => $request->grand_total, 'credit' => 0]);
                    
                \App\Models\JournalItem::where('journal_entry_id', $journal->id)
                    ->where('account_id', $equityAcc)
                    ->update(['debit' => 0, 'credit' => $request->grand_total]);
            }
            // ----------------------------------------------------------------

            DB::commit();
            return response()->json([
                'success' => true, 
                'message' => 'Perubahan saldo awal piutang dan jurnal berhasil disimpan!'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false, 
                'message' => 'Gagal memperbarui data: ' . $e->getMessage()
            ], 500);
        }
    }

    // --- 5. HAPUS DATA (DENGAN PENGHAPUSAN JURNAL TERKAIT) ---
    public function destroy(Request $request, $id)
    {
        $user = $request->user();

        DB::beginTransaction();
        try {
            $sale = Sale::where('is_initial_debt', true)->findOrFail($id);
            
            // PERBAIKAN ENTERPRISE: Proteksi Delete Silang Cabang
            if ($user && $user->role !== 'owner' && $sale->branch_id !== $user->branch_id) {
                return response()->json(['success' => false, 'message' => 'Akses ditolak: Data piutang ini bukan wewenang cabang Anda.'], 403);
            }

            // ----------------------------------------------------------------
            // HAPUS JURNAL TERKAIT SEBELUM MENGHAPUS TRANSAKSI
            // ----------------------------------------------------------------
            $journal = \App\Models\JournalEntry::where('reference', $sale->invoice_number)
                ->where('source_type', 'migration_receivable')
                ->first();
                
            if ($journal) {
                \App\Models\JournalItem::where('journal_entry_id', $journal->id)->delete();
                $journal->delete();
            }
            // ----------------------------------------------------------------

            $sale->delete();

            DB::commit();
            return response()->json([
                'success' => true, 
                'message' => 'Data piutang awal dan jurnal terkait berhasil dihapus.'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false, 
                'message' => 'Gagal menghapus data: ' . $e->getMessage()
            ], 500);
        }
    }

    // --- 6. PREVIEW CSV (LOGIKA LENGKAP) ---
    public function previewCsv(Request $request)
    {
        $request->validate(['file' => 'required|mimes:csv,txt']);
        
        $user = $request->user();
        $file = $request->file('file');
        $handle = fopen($file->getPathname(), "r");
        
        fgetcsv($handle, 1000, ","); 
        
        $previewData = [];
        $row = 2;

        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $noFaktur = trim($data[0] ?? '');
            $kodePelanggan = trim($data[1] ?? '');
            $nominal = trim($data[2] ?? 0);
            $tglFaktur = trim($data[3] ?? '');
            $tglTempo = trim($data[4] ?? '');

            $isValid = true;
            $errors = [];

            // PERBAIKAN ENTERPRISE: Validasi Customer berdasarkan Kode dan Cabang
            $customerQuery = Customer::with('branch')->where('customer_code', $kodePelanggan);
            if ($user && $user->role !== 'owner') {
                $customerQuery->where('branch_id', $user->branch_id);
            }
            $customer = $customerQuery->first();
            
            if (!$customer) {
                $isValid = false;
                $errors[] = "Kode pelanggan '$kodePelanggan' tidak ditemukan atau bukan milik cabang Anda.";
            }

            if (empty($noFaktur)) {
                $isValid = false;
                $errors[] = "Nomor faktur tidak boleh kosong.";
            }

            if (!is_numeric($nominal) || $nominal <= 0) {
                $isValid = false;
                $errors[] = "Nominal piutang harus angka valid.";
            }

            $parsedCreatedAt = $tglFaktur ? Carbon::parse($tglFaktur)->format('Y-m-d') : Carbon::now()->subMonth()->format('Y-m-d');
            $parsedDueDate = $tglTempo ? Carbon::parse($tglTempo)->format('Y-m-d') : Carbon::parse($parsedCreatedAt)->addDays(14)->format('Y-m-d');

            $previewData[] = [
                'row' => $row,
                'invoice_number' => $noFaktur,
                'customer_code' => $kodePelanggan,
                'customer_name' => $customer ? $customer->name : 'N/A',
                'branch_id' => $customer ? $customer->branch_id : null,
                'branch_name' => $customer && $customer->branch ? $customer->branch->name : 'N/A',
                'customer_id' => $customer ? $customer->id : null,
                'grand_total' => $nominal,
                'created_at' => $parsedCreatedAt,
                'due_date' => $parsedDueDate,
                'is_valid' => $isValid,
                'errors' => implode(", ", $errors)
            ];
            $row++;
        }
        fclose($handle);

        return response()->json([
            'success' => true, 
            'data' => $previewData
        ]);
    }

    // --- 7. IMPORT DATA MASSAL (UTUH DENGAN STRICT VALIDATION) ---
    public function importData(Request $request)
    {
        $items = $request->items;
        $successCount = 0;
        $user = $request->user();

        DB::beginTransaction();
        try {
            $receivableAcc = AccountingService::getAccountId('default_receivable_account');
            $equityAcc     = AccountingService::getAccountId('default_migration_equity_account');

            if (!$receivableAcc || !$equityAcc) {
                throw new \Exception("Sistem Gagal: Akun Piutang atau Akun Modal untuk migrasi belum tersedia di Master Akun Global.");
            }

            foreach ($items as $item) {
                if (!$item['is_valid']) continue;

                // PERBAIKAN ENTERPRISE: Lapis kedua proteksi saat mengeksekusi import
                if ($user && $user->role !== 'owner' && (int)$item['branch_id'] !== (int)$user->branch_id) {
                    continue; // Skip data yang mencoba membajak cabang lain
                }

                Sale::create([
                    'branch_id' => $item['branch_id'],
                    'user_id' => $user->id,
                    'customer_id' => $item['customer_id'],
                    'customer_name' => $item['customer_name'],
                    'invoice_number' => $item['invoice_number'],
                    'subtotal' => $item['grand_total'],
                    'grand_total' => $item['grand_total'],
                    'payment_method' => 'kredit',
                    'payment_status' => 'pending',
                    'is_initial_debt' => true,
                    'created_at' => Carbon::parse($item['created_at']),
                    'due_date' => Carbon::parse($item['due_date']),
                ]);

                // ----------------------------------------------------------------
                // JURNAL AKUNTANSI: SALDO AWAL PIUTANG (CSV)
                // ----------------------------------------------------------------
                AccountingService::log([
                    'branch_id'   => $item['branch_id'],
                    'entry_date'  => Carbon::parse($item['created_at'])->toDateString(),
                    'description' => "Saldo Awal Piutang: " . $item['customer_name'],
                    'reference'   => $item['invoice_number'],
                    'source_type' => 'migration_receivable',
                    'user_id'     => $user->id,
                    'items' => [
                        ['account_id' => $receivableAcc, 'debit' => $item['grand_total'], 'credit' => 0],
                        ['account_id' => $equityAcc, 'debit' => 0, 'credit' => $item['grand_total']],
                    ]
                ]);
                // ----------------------------------------------------------------

                $successCount++;
            }
            DB::commit();
            return response()->json([
                'success' => true, 
                'message' => $successCount . ' data saldo piutang berhasil diimport dan dijurnal ke sistem.'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false, 
                'message' => 'Gagal melakukan import massal: ' . $e->getMessage()
            ], 500);
        }
    }
}