<?php

namespace App\Http\Controllers\Api;

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

/**
 * SalesReturnController
 * * Modul ini menangani alur bisnis Retur Penjualan secara Enterprise.
 */
class SalesReturnController extends Controller
{
    /**
     * 1. CARI FAKTUR & ISI BARANGNYA
     */
    public function searchInvoice(Request $request)
    {
        $search = $request->query('search');
        $user = auth()->user();

        if (!$search) {
            return response()->json([
                'success' => false, 
                'message' => 'Kata kunci pencarian tidak boleh kosong.'
            ]);
        }

        try {
            $baseQuery = DB::table('sales_invoices')
                ->join('customers', 'sales_invoices.customer_id', '=', 'customers.id')
                ->select(
                    'sales_invoices.*', 
                    'customers.name as customer_name'
                );

            // PERBAIKAN ENTERPRISE: Isolasi Pencarian Faktur
            if ($user && $user->role !== 'owner') {
                $baseQuery->where('sales_invoices.branch_id', $user->branch_id);
            }

            $invoice = (clone $baseQuery)
                ->where('sales_invoices.invoice_number', strtoupper($search))
                ->first();

            if ($invoice) {
                $items = DB::table('sale_items')
                    ->join('products', 'sale_items.product_id', '=', 'products.id')
                    ->join('sales', 'sale_items.sale_id', '=', 'sales.id')
                    ->where('sales.sales_invoice_id', $invoice->id)
                    ->whereIn('products.product_type', ['trading', 'finished_good'])
                    ->select(
                        'sale_items.product_id',
                        'sale_items.product_name',
                        'sale_items.quantity',
                        'sale_items.unit_price',
                        'products.unit as master_unit', 
                        'products.buy_price as hpp_unit' 
                    )
                    ->get();

                return response()->json([
                    'success' => true,
                    'is_list' => false,
                    'invoice' => $invoice,
                    'items' => $items
                ]);
            }

            $invoices = (clone $baseQuery)
                ->where('customers.name', 'LIKE', "%{$search}%")
                ->orderBy('sales_invoices.created_at', 'desc')
                ->limit(15)
                ->get();

            if ($invoices->isNotEmpty()) {
                return response()->json([
                    'success' => true,
                    'is_list' => true,
                    'data' => $invoices
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'Data faktur atau nama pelanggan tidak ditemukan di cabang Anda.'
            ], 404);

        } catch (\Exception $e) {
            Log::error("Search Invoice Error: " . $e->getMessage());
            return response()->json([
                'success' => false, 
                'message' => 'Terjadi kesalahan sistem saat mencari data.'
            ], 500);
        }
    }

    /**
     * 2. SIMPAN PENGAJUAN RETUR (STATUS PENDING)
     */
    public function storeRequest(Request $request)
    {
        $request->validate([
            'invoice_id' => 'required',
            'customer_id' => 'required',
            'items' => 'required|array',
            'items.*.product_id' => 'required',
            'items.*.qty_planned' => 'required|numeric|min:0.1',
        ]);

        DB::beginTransaction();

        try {
            $user = auth()->user();
            $branchId = ($user && $user->role !== 'owner') ? $user->branch_id : ($request->branch_id ?? $user->branch_id ?? 1);
            $userId = $user->id;
            
            // PERBAIKAN ENTERPRISE: Cegah retur silang cabang
            $invoice = DB::table('sales_invoices')->where('id', $request->invoice_id)->first();
            if (!$invoice || ($user->role !== 'owner' && $invoice->branch_id !== $branchId)) {
                throw new \Exception("Akses ditolak: Faktur tidak ditemukan atau bukan wewenang cabang Anda.");
            }

            $returnNumber = 'RJ-' . date('Ymd') . '-' . strtoupper(bin2hex(random_bytes(2)));

            $returnId = DB::table('sales_returns')->insertGetId([
                'return_number' => $returnNumber,
                'branch_id' => $branchId,
                'customer_id' => $request->customer_id,
                'sales_invoice_id' => $request->invoice_id,
                'created_by' => $userId,
                'status' => 'pending',
                'note' => $request->note,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ]);

            foreach ($request->items as $item) {
                DB::table('sales_return_items')->insert([
                    'sales_return_id' => $returnId,
                    'product_id' => $item['product_id'],
                    'qty_planned' => $item['qty_planned'],
                    'qty_received' => 0, 
                    'unit_name' => $item['unit_name'],
                    'price_at_invoice' => $item['unit_price'],
                    'reason' => $item['reason'] ?? 'Retur Barang',
                    'condition' => 'good' 
                ]);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Pengajuan retur berhasil disimpan.',
                'return_number' => $returnNumber
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("Store Return Error: " . $e->getMessage());
            return response()->json([
                'success' => false, 
                'message' => 'Gagal menyimpan pengajuan: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 3. GET DAFTAR RETUR (GUDANG & KEUANGAN)
     */
    public function getPendingReturns(Request $request)
    {
        try {
            $user = auth()->user();
            $status = $request->query('status', 'pending');

            $query = DB::table('sales_returns')
                ->join('customers', 'sales_returns.customer_id', '=', 'customers.id')
                ->select(
                    'sales_returns.id', 
                    'sales_returns.return_number', 
                    'sales_returns.status', 
                    'sales_returns.created_at', 
                    'customers.name as customer_name'
                )
                ->where('sales_returns.status', $status);

            if ($user->role !== 'owner') {
                $query->where('sales_returns.branch_id', $user->branch_id);
            }

            $returns = $query->orderBy('sales_returns.created_at', 'desc')->get();

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

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

    /**
     * 4. DETAIL RETUR UNTUK PROSES VERIFIKASI
     */
    public function getReturnDetail($id)
    {
        try {
            $user = auth()->user();

            $header = DB::table('sales_returns')
                ->join('customers', 'sales_returns.customer_id', '=', 'customers.id')
                ->join('sales_invoices', 'sales_returns.sales_invoice_id', '=', 'sales_invoices.id')
                ->select(
                    'sales_returns.*', 
                    'customers.name as customer_name', 
                    'sales_invoices.invoice_number as ref_invoice',
                    'sales_invoices.tax_percentage'
                )
                ->where('sales_returns.id', $id)
                ->first();

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

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

            $items = DB::table('sales_return_items')
                ->join('products', 'sales_return_items.product_id', '=', 'products.id')
                ->select(
                    'sales_return_items.*', 
                    'products.name as product_name',
                    'products.buy_price as hpp_unit'
                )
                ->where('sales_return_id', $id)
                ->whereIn('products.product_type', ['trading', 'finished_good'])
                ->get();

            return response()->json([
                'success' => true, 
                'header' => $header, 
                'items' => $items
            ]);

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

    /**
     * 5. VERIFIKASI GUDANG (INBOUND)
     */
    public function verifyIncomingReturn(Request $request, $id)
    {
        $request->validate([
            'items' => 'required|array',
            'items.*.id' => 'required',
            'items.*.qty_received' => 'required|numeric|min:0',
            'items.*.condition' => 'required|in:good,bad',
        ]);

        DB::beginTransaction();

        try {
            $user = auth()->user();
            $returnHeader = DB::table('sales_returns')->where('id', $id)->first();
            
            if (!$returnHeader) throw new \Exception("Data retur tidak ditemukan.");

            // PERBAIKAN ENTERPRISE: Proteksi Eksekusi Lintas Cabang
            if ($user->role !== 'owner' && $returnHeader->branch_id !== $user->branch_id) {
                throw new \Exception("Akses ditolak: Anda tidak memiliki wewenang untuk memverifikasi dokumen cabang lain.");
            }

            $branchId = $returnHeader->branch_id;
            $userId = $user->id;

            foreach ($request->items as $it) {
                DB::table('sales_return_items')
                    ->where('id', $it['id'])
                    ->update([
                        'qty_received' => $it['qty_received'],
                        'condition' => $it['condition']
                    ]);

                if ($it['qty_received'] > 0) {
                    $itemData = DB::table('sales_return_items')->where('id', $it['id'])->first();
                    
                    if ($it['condition'] === 'good') {
                        DB::table('product_stocks')
                            ->where('product_id', $itemData->product_id)
                            ->where('branch_id', $branchId)
                            ->increment('quantity', $it['qty_received']);
                    } else {
                        DB::table('product_stocks')
                            ->where('product_id', $itemData->product_id)
                            ->where('branch_id', $branchId)
                            ->increment('reserved_qty', $it['qty_received']);
                    }

                    DB::table('stock_transactions')->insert([
                        'branch_id' => $branchId,
                        'product_id' => $itemData->product_id,
                        'type' => 'sale_return',
                        'input_quantity' => $it['qty_received'],
                        'input_unit' => $itemData->unit_name,
                        'actual_quantity' => $it['qty_received'],
                        'user_id' => $userId,
                        'note' => 'Cek Fisik Retur: ' . $returnHeader->return_number . ' (' . strtoupper($it['condition']) . ')',
                        'created_at' => Carbon::now()
                    ]);
                }
            }

            DB::table('sales_returns')->where('id', $id)->update([
                'status' => 'received',
                'updated_at' => Carbon::now()
            ]);

            DB::commit();

            return response()->json([
                'success' => true, 
                'message' => 'Verifikasi fisik selesai. Stok telah dialokasikan.'
            ]);

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

    /**
     * 6. OTORISASI KEUANGAN & PENJURNALAN (LOGIKA PPN + PERSEDIAAN + AUTO DEPOSIT)
     */
    public function authorizeFinance($id)
    {
        DB::beginTransaction();

        try {
            $user = auth()->user();
            $return = DB::table('sales_returns')->where('id', $id)->first();
            
            if (!$return || $return->status !== 'received') {
                return response()->json([
                    'success' => false, 
                    'message' => 'Dokumen belum melalui tahap verifikasi gudang.'
                ], 400);
            }

            // PERBAIKAN ENTERPRISE: Keamanan Eksekusi Keuangan
            if ($user->role !== 'owner' && $return->branch_id !== $user->branch_id) {
                return response()->json(['success' => false, 'message' => 'Akses ditolak: Otorisasi lintas cabang tidak diizinkan.'], 403);
            }

            $originInvoice = DB::table('sales_invoices')->where('id', $return->sales_invoice_id)->first();
            $taxRate = $originInvoice->tax_percentage ?? 0;
            $sisaPiutangFaktur = (float) $originInvoice->grand_total; 

            $items = DB::table('sales_return_items')
                ->join('products', 'sales_return_items.product_id', '=', 'products.id')
                ->select(
                    'sales_return_items.*', 
                    'products.buy_price as hpp_satuan'
                )
                ->where('sales_return_id', $id)
                ->get();

            $totalDPP = 0;    
            $totalHPP = 0;    

            foreach ($items as $item) {
                $totalDPP += ($item->qty_received * $item->price_at_invoice);
                $totalHPP += ($item->qty_received * $item->hpp_satuan);
            }

            $totalPPN = ($totalDPP * $taxRate) / 100;
            $totalNilaiRetur = $totalDPP + $totalPPN;

            $nilaiDipotongKePiutang = $totalNilaiRetur;
            $nilaiMasukKeDeposit = 0;

            if ($totalNilaiRetur > $sisaPiutangFaktur) {
                $nilaiDipotongKePiutang = $sisaPiutangFaktur; 
                $nilaiMasukKeDeposit = $totalNilaiRetur - $sisaPiutangFaktur; 
            }

            DB::table('sales_returns')->where('id', $id)->update([
                'status' => 'completed',
                'total_refund_value' => $totalNilaiRetur,
                'updated_at' => Carbon::now()
            ]);

            if ($totalNilaiRetur > 0) {
                if ($nilaiDipotongKePiutang > 0) {
                    DB::table('sales_invoices')
                        ->where('id', $return->sales_invoice_id)
                        ->decrement('grand_total', $nilaiDipotongKePiutang);
                }

                if ($nilaiMasukKeDeposit > 0) {
                    DB::table('customers')
                        ->where('id', $return->customer_id)
                        ->increment('deposit_balance', $nilaiMasukKeDeposit);
                }
                
                // =========================================================================
                // B. PENCATATAN JURNAL AKUNTANSI OTOMATIS DENGAN STRICT GL ACCOUNTING SERVICE
                // =========================================================================
                $akunRetur = AccountingService::getAccountId('sales_return_account'); 
                $akunPPN = AccountingService::getAccountId('ppn_output_account');
                $akunPiutang = AccountingService::getAccountId('receivable_account');
                $akunDeposit = AccountingService::getAccountId('deposit_pelanggan') ?? DB::table('accounts')->where('code', '2106')->value('id'); 
                $akunPersediaan = AccountingService::getAccountId('inventory_account');
                $akunHPP = AccountingService::getAccountId('cost_of_goods_sold_account');

                if (!$akunRetur || !$akunPiutang || !$akunPersediaan || !$akunHPP) {
                    throw new \Exception("Sistem Gagal: Master Akun Global (Retur/Piutang/Persediaan/HPP) belum dikonfigurasi di Pengaturan Akuntansi.");
                }

                $journalItems = [];

                // DEBIT: Akun Retur Penjualan (Mengurangi Pendapatan)
                $journalItems[] = ['account_id' => $akunRetur, 'debit' => $totalDPP, 'credit' => 0];

                // DEBIT: Akun PPN Keluaran (Membatalkan PPN)
                if ($totalPPN > 0 && $akunPPN) {
                    $journalItems[] = ['account_id' => $akunPPN, 'debit' => $totalPPN, 'credit' => 0];
                }

                // KREDIT: Akun Piutang Pelanggan (Potong Tagihan)
                if ($nilaiDipotongKePiutang > 0) {
                    $journalItems[] = ['account_id' => $akunPiutang, 'debit' => 0, 'credit' => $nilaiDipotongKePiutang];
                }

                // KREDIT: Akun Titipan Pelanggan (Kelebihan Retur)
                if ($nilaiMasukKeDeposit > 0 && $akunDeposit) {
                    $journalItems[] = ['account_id' => $akunDeposit, 'debit' => 0, 'credit' => $nilaiMasukKeDeposit];
                }

                // SET 2: JURNAL PERSEDIAAN & HPP
                if ($totalHPP > 0) {
                    // DEBIT: Persediaan Bertambah
                    $journalItems[] = ['account_id' => $akunPersediaan, 'debit' => $totalHPP, 'credit' => 0];
                    // KREDIT: HPP Berkurang
                    $journalItems[] = ['account_id' => $akunHPP, 'debit' => 0, 'credit' => $totalHPP];
                }

                AccountingService::log([
                    'branch_id' => $return->branch_id,
                    'entry_date' => date('Y-m-d'),
                    'description' => "Otorisasi Retur Penjualan: " . $return->return_number,
                    'reference' => $return->return_number,
                    'source_type' => 'sales_return',
                    'user_id' => auth()->id(),
                    'items' => $journalItems
                ]);
                // =========================================================================
            }

            DB::commit();

            $msg = 'Otorisasi Keuangan Berhasil.';
            if ($nilaiMasukKeDeposit > 0) {
                $msg .= ' Sisa retur Rp ' . number_format($nilaiMasukKeDeposit, 0, ',', '.') . ' telah dimasukkan ke Deposit Pelanggan.';
            }

            return response()->json([
                'success' => true, 
                'message' => $msg
            ]);
            
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("Finance Auth Error: " . $e->getMessage());
            return response()->json([
                'success' => false, 
                'message' => 'Terjadi kesalahan proses keuangan: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 7. LAPORAN BARANG RUSAK (BAD STOCK REPORT)
     */
    public function getBadStockReport(Request $request)
    {
        try {
            $user = auth()->user();
            
            $query = DB::table('sales_return_items')
                ->join('sales_returns', 'sales_return_items.sales_return_id', '=', 'sales_returns.id')
                ->join('customers', 'sales_returns.customer_id', '=', 'customers.id')
                ->join('products', 'sales_return_items.product_id', '=', 'products.id')
                ->select(
                    'sales_returns.return_number',
                    'customers.name as customer_name',
                    'products.name as product_name',
                    'sales_return_items.qty_received',
                    'sales_return_items.unit_name',
                    'sales_return_items.reason',
                    'sales_returns.created_at as return_date'
                )
                ->where('sales_return_items.condition', 'bad')
                ->where('sales_return_items.qty_received', '>', 0);

            if ($user->role !== 'owner') {
                $query->where('sales_returns.branch_id', $user->branch_id);
            }

            $report = $query->orderBy('sales_returns.created_at', 'desc')->get();

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

        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Gagal muat laporan bad stock.'], 500);
        }
    }

    /**
     * 8. FUNGSI SINKRONISASI
     */
    public function syncMissingInventoryJournals()
    {
        return response()->json([
            'success' => true, 
            'message' => 'Fungsi Sinkronisasi dinonaktifkan karena sistem AccountingService yang baru sudah memastikan persediaan tercatat real-time.'
        ]);
    }

    /**
     * EKSEKUSI A: PEMUSNAHAN BARANG RUSAK (DISPOSAL)
     */
    public function disposeBadStock(Request $request)
    {
        $request->validate([
            'branch_id' => 'required',
            'product_id' => 'required',
            'qty_to_dispose' => 'required|numeric|min:0.1',
            'reason' => 'required|string'
        ]);

        DB::beginTransaction();

        try {
            $user = auth()->user();
            // PERBAIKAN ENTERPRISE: Keamanan Cabang Eksekusi
            $branchId = ($user->role !== 'owner') ? $user->branch_id : $request->branch_id;
            
            $productId = $request->product_id;
            $qtyToDispose = $request->qty_to_dispose;

            $stock = DB::table('product_stocks')
                ->where('product_id', $productId)
                ->where('branch_id', $branchId)
                ->first();

            if (!$stock || $stock->reserved_qty < $qtyToDispose) {
                return response()->json(['success' => false, 'message' => 'Stok rusak (Bad Stock) tidak mencukupi untuk dimusnahkan.'], 400);
            }

            $product = DB::table('products')->where('id', $productId)->first();
            $totalDisposalValue = $qtyToDispose * $product->buy_price; 

            DB::table('product_stocks')
                ->where('id', $stock->id)
                ->decrement('reserved_qty', $qtyToDispose);

            DB::table('stock_transactions')->insert([
                'branch_id' => $branchId,
                'product_id' => $productId,
                'type' => 'disposal',
                'input_quantity' => -$qtyToDispose,
                'input_unit' => $product->unit,
                'actual_quantity' => -$qtyToDispose,
                'user_id' => auth()->id(),
                'note' => 'Pemusnahan Barang Rusak: ' . $request->reason,
                'created_at' => Carbon::now()
            ]);

            // =========================================================================
            // JURNAL AKUNTANSI PEMUSNAHAN DENGAN STRICT GL
            // =========================================================================
            if ($totalDisposalValue > 0) {
                $akunBebanRusak = AccountingService::getAccountId('beban_kerusakan_barang'); 
                $akunPersediaan = AccountingService::getAccountId('inventory_account'); 

                if (!$akunBebanRusak || !$akunPersediaan) {
                    throw new \Exception("Sistem Gagal: Master Akun Beban Kerusakan / Persediaan belum dikonfigurasi.");
                }

                AccountingService::log([
                    'branch_id' => $branchId,
                    'entry_date' => date('Y-m-d'),
                    'description' => "Pemusnahan Barang Rusak: " . $product->name,
                    'reference' => 'DISP-' . date('YmdHis'),
                    'source_type' => 'stock_disposal',
                    'user_id' => auth()->id(),
                    'items' => [
                        // DEBIT: Beban Kerusakan / Selisih Stok
                        ['account_id' => $akunBebanRusak, 'debit' => $totalDisposalValue, 'credit' => 0],
                        // KREDIT: Persediaan Barang
                        ['account_id' => $akunPersediaan, 'debit' => 0, 'credit' => $totalDisposalValue]
                    ]
                ]);
            }
            // =========================================================================

            DB::commit();
            return response()->json(['success' => true, 'message' => 'Barang rusak berhasil dimusnahkan dan dijurnal ke Beban Kerusakan.']);

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

    /**
     * EKSEKUSI B: RETUR KE SUPPLIER / PABRIK (PURCHASE RETURN)
     */
    public function returnToSupplier(Request $request)
    {
        $request->validate([
            'branch_id' => 'required',
            'supplier_id' => 'required',
            'product_id' => 'required',
            'qty_to_return' => 'required|numeric|min:0.1',
            'return_type' => 'required|in:deduct_payable,cash_refund',
        ]);

        DB::beginTransaction();

        try {
            $user = auth()->user();
            // PERBAIKAN ENTERPRISE: Keamanan Cabang Eksekusi
            $branchId = ($user->role !== 'owner') ? $user->branch_id : $request->branch_id;
            
            $productId = $request->product_id;
            $qtyToReturn = $request->qty_to_return;
            $returnType = $request->return_type;
            
            $returnNumber = 'RB-' . date('Ymd') . '-' . rand(1000, 9999);

            $stock = DB::table('product_stocks')
                ->where('product_id', $productId)
                ->where('branch_id', $branchId)
                ->first();

            if (!$stock || $stock->reserved_qty < $qtyToReturn) {
                return response()->json(['success' => false, 'message' => 'Stok rusak (Bad Stock) tidak mencukupi untuk diretur ke pabrik.'], 400);
            }

            $product = DB::table('products')->where('id', $productId)->first();
            $totalReturnValue = $qtyToReturn * $product->buy_price;

            DB::table('product_stocks')
                ->where('id', $stock->id)
                ->decrement('reserved_qty', $qtyToReturn);

            DB::table('stock_transactions')->insert([
                'branch_id' => $branchId,
                'product_id' => $productId,
                'type' => 'purchase_return',
                'input_quantity' => -$qtyToReturn,
                'input_unit' => $product->unit,
                'actual_quantity' => -$qtyToReturn,
                'user_id' => auth()->id(),
                'note' => 'Retur ke Pabrik: ' . $returnNumber,
                'created_at' => Carbon::now()
            ]);

            // =========================================================================
            // JURNAL AKUNTANSI RETUR PABRIK DENGAN STRICT GL
            // =========================================================================
            if ($totalReturnValue > 0) {
                $akunHutang = AccountingService::getAccountId('payable_account');
                $akunPersediaan = AccountingService::getAccountId('inventory_account');
                $akunPiutangKlaim = AccountingService::getAccountId('piutang_retur_supplier');

                if (!$akunHutang || !$akunPersediaan || !$akunPiutangKlaim) {
                    throw new \Exception("Sistem Gagal: Master Akun Hutang/Persediaan/Piutang Klaim belum dikonfigurasi.");
                }

                $debitAccountId = ($returnType === 'deduct_payable') ? $akunHutang : $akunPiutangKlaim;

                AccountingService::log([
                    'branch_id' => $branchId,
                    'entry_date' => date('Y-m-d'),
                    'description' => "Retur Barang Rusak ke Pabrik: " . $returnNumber,
                    'reference' => $returnNumber,
                    'source_type' => 'purchase_return',
                    'user_id' => auth()->id(),
                    'items' => [
                        // DEBIT: Hutang Dagang ATAU Piutang Retur Supplier
                        ['account_id' => $debitAccountId, 'debit' => $totalReturnValue, 'credit' => 0],
                        // KREDIT: Persediaan Barang 
                        ['account_id' => $akunPersediaan, 'debit' => 0, 'credit' => $totalReturnValue]
                    ]
                ]);
            }
            // =========================================================================

            DB::commit();
            return response()->json(['success' => true, 'message' => 'Berhasil diretur ke pabrik. Hutang/Piutang Supplier telah diperbarui.']);

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

    /**
     * 9. PEMBATALAN RETUR (VOID / CANCEL)
     */
    public function cancelReturn(Request $request, $id)
    {
        $request->validate([
            'cancel_reason' => 'required|string|min:5'
        ]);

        DB::beginTransaction();

        try {
            $user = auth()->user();
            $return = DB::table('sales_returns')->where('id', $id)->first();

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

            // PERBAIKAN ENTERPRISE: Keamanan Eksekusi Pembatalan
            if ($user->role !== 'owner' && $return->branch_id !== $user->branch_id) {
                return response()->json(['success' => false, 'message' => 'Akses ditolak: Dokumen ini bukan wewenang cabang Anda.'], 403);
            }

            if ($return->status === 'cancelled') {
                return response()->json(['success' => false, 'message' => 'Dokumen sudah berstatus batal.'], 400);
            }

            $cancelReason = "DIBATALKAN: " . $request->cancel_reason . " (Waktu: " . Carbon::now()->toDateTimeString() . ")";
            $newNote = $return->note ? $return->note . "\n" . $cancelReason : $cancelReason;

            $statusAsal = $return->status;

            // Reverse STOK
            if ($statusAsal === 'received' || $statusAsal === 'completed') {
                $items = DB::table('sales_return_items')->where('sales_return_id', $id)->get();
                
                foreach ($items as $item) {
                    if ($item->qty_received > 0) {
                        $currentStock = DB::table('product_stocks')
                            ->where('product_id', $item->product_id)
                            ->where('branch_id', $return->branch_id)
                            ->first();

                        if ($item->condition === 'good') {
                            if (!$currentStock || $currentStock->quantity < $item->qty_received) {
                                throw new \Exception("Gagal Batal! Stok barang bagus {$item->unit_name} sudah terpakai/terjual.");
                            }
                            DB::table('product_stocks')
                                ->where('id', $currentStock->id)
                                ->decrement('quantity', $item->qty_received);
                        } else { 
                            if (!$currentStock || $currentStock->reserved_qty < $item->qty_received) {
                                throw new \Exception("Gagal Batal! Stok rusak {$item->unit_name} sudah dimusnahkan atau diretur ke pabrik.");
                            }
                            DB::table('product_stocks')
                                ->where('id', $currentStock->id)
                                ->decrement('reserved_qty', $item->qty_received);
                        }

                        DB::table('stock_transactions')->insert([
                            'branch_id' => $return->branch_id,
                            'product_id' => $item->product_id,
                            'type' => 'sale_return_void',
                            'input_quantity' => -$item->qty_received,
                            'input_unit' => $item->unit_name,
                            'actual_quantity' => -$item->qty_received,
                            'user_id' => auth()->id(),
                            'note' => 'VOID RETUR: ' . $return->return_number,
                            'created_at' => Carbon::now()
                        ]);
                    }
                }
            }

            // Reverse PIUTANG & JURNAL
            if ($statusAsal === 'completed') {
                $originInvoice = DB::table('sales_invoices')->where('id', $return->sales_invoice_id)->first();
                $taxRate = $originInvoice->tax_percentage ?? 0;

                $items = DB::table('sales_return_items')
                    ->join('products', 'sales_return_items.product_id', '=', 'products.id')
                    ->select('sales_return_items.*', 'products.buy_price as hpp_satuan')
                    ->where('sales_return_id', $id)
                    ->get();

                $totalDPP = 0;
                $totalHPP = 0;
                foreach ($items as $item) {
                    $totalDPP += ($item->qty_received * $item->price_at_invoice);
                    $totalHPP += ($item->qty_received * $item->hpp_satuan);
                }
                $totalPPN = ($totalDPP * $taxRate) / 100;
                $totalNilaiRetur = $totalDPP + $totalPPN;

                DB::table('sales_invoices')->where('id', $return->sales_invoice_id)->increment('grand_total', $totalNilaiRetur);
                
                // =========================================================================
                // JURNAL PEMBALIK (VOID RETUR) MENGGUNAKAN STRICT GL ACCOUNTING SERVICE
                // =========================================================================
                $akunRetur = AccountingService::getAccountId('sales_return_account'); 
                $akunPPN = AccountingService::getAccountId('ppn_output_account');
                $akunPiutang = AccountingService::getAccountId('receivable_account');
                $akunPersediaan = AccountingService::getAccountId('inventory_account');
                $akunHPP = AccountingService::getAccountId('cost_of_goods_sold_account');

                if (!$akunRetur || !$akunPiutang || !$akunPersediaan || !$akunHPP) {
                    throw new \Exception("Sistem Gagal: Master Akun Global (Retur/Piutang/Persediaan/HPP) belum dikonfigurasi.");
                }

                $journalItems = [];

                // DEBIT: Piutang Pelanggan (Tagihan Hidup Kembali)
                $journalItems[] = ['account_id' => $akunPiutang, 'debit' => $totalNilaiRetur, 'credit' => 0];
                
                // KREDIT: Retur Penjualan
                $journalItems[] = ['account_id' => $akunRetur, 'debit' => 0, 'credit' => $totalDPP];
                
                // KREDIT: PPN Keluaran
                if ($totalPPN > 0 && $akunPPN) {
                    $journalItems[] = ['account_id' => $akunPPN, 'debit' => 0, 'credit' => $totalPPN];
                }

                // BALIKAN PERSEDIAAN & HPP
                if ($totalHPP > 0) {
                    // DEBIT: HPP
                    $journalItems[] = ['account_id' => $akunHPP, 'debit' => $totalHPP, 'credit' => 0];
                    // KREDIT: Persediaan
                    $journalItems[] = ['account_id' => $akunPersediaan, 'debit' => 0, 'credit' => $totalHPP];
                }

                AccountingService::log([
                    'branch_id' => $return->branch_id,
                    'entry_date' => date('Y-m-d'),
                    'description' => "Jurnal Pembalik (Batal Retur): " . $return->return_number,
                    'reference' => $return->return_number . '-VOID',
                    'source_type' => 'sale_return_void',
                    'user_id' => auth()->id(),
                    'items' => $journalItems
                ]);
                // =========================================================================
            }

            DB::table('sales_returns')->where('id', $id)->update([
                'status' => 'cancelled',
                'note' => $newNote,
                'updated_at' => Carbon::now()
            ]);

            DB::commit();
            return response()->json([
                'success' => true,
                'message' => "Dokumen retur berhasil dibatalkan secara sistem. Semua jurnal dan mutasi stok telah dibalikkan."
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("Cancel Return Error: " . $e->getMessage());
            return response()->json([
                'success' => false, 
                'message' => 'Gagal membatalkan dokumen: ' . $e->getMessage()
            ], 500);
        }
    }
}