<?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; 

class StockWriteOffController extends Controller
{
    /**
     * TAMPILKAN DAFTAR RIWAYAT PEMUSNAHAN (UNTUK LAPORAN)
     */
    public function index(Request $request)
    {
        try {
            $user = auth()->user();
            $query = DB::table('stock_write_offs as swo')
                ->join('branches as b', 'swo.branch_id', '=', 'b.id')
                ->leftJoin('users as u', 'swo.created_by', '=', 'u.id')
                ->select(
                    'swo.*', 
                    'b.name as branch_name', 
                    'u.name as created_by_name'
                )
                ->orderBy('swo.created_at', 'desc');

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

            return response()->json(['success' => true, 'data' => $query->get()]);
        } catch (\Exception $e) {
            Log::error("Get Write-Off List Error: " . $e->getMessage());
            return response()->json(['success' => false, 'message' => 'Gagal memuat data laporan'], 500);
        }
    }

    /**
     * DETAIL BERITA ACARA PEMUSNAHAN (BAP)
     */
    public function show($id)
    {
        try {
            $user = auth()->user();

            $query = DB::table('stock_write_offs as swo')
                ->join('branches as b', 'swo.branch_id', '=', 'b.id')
                ->leftJoin('users as u', 'swo.created_by', '=', 'u.id')
                ->select('swo.*', 'b.name as branch_name', 'u.name as created_by_name')
                ->where('swo.id', $id);

            // PERBAIKAN ENTERPRISE: Proteksi IDOR Lintas Cabang
            if ($user && $user->role !== 'owner') {
                $query->where('swo.branch_id', $user->branch_id);
            }

            $header = $query->first();

            if (!$header) throw new \Exception("Dokumen tidak ditemukan atau bukan wewenang cabang Anda.");

            $items = DB::table('stock_write_off_items as swoi')
                ->join('products as p', 'swoi.product_id', '=', 'p.id')
                ->select('swoi.*', 'p.sku', 'p.name as product_name', 'p.variant_name')
                ->where('swoi.stock_write_off_id', $id)
                ->get();

            return response()->json([
                'success' => true, 
                'data' => [
                    'header' => $header,
                    'items' => $items
                ]
            ]);
        } catch (\Exception $e) {
            Log::error("Get BAP Detail Error: " . $e->getMessage());
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    /**
     * EKSEKUSI PEMUSNAHAN
     */
    public function store(Request $request)
    {
        $request->validate([
            'branch_id' => 'required',
            'write_off_date' => 'required|date',
            'notes' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required',
            'items.*.qty' => 'required|numeric|min:1',
        ]);

        try {
            return DB::transaction(function () use ($request) {
                $user = auth()->user();
                
                // PERBAIKAN ENTERPRISE: Kunci Otorisasi Cabang Pengirim
                $branchId = ($user && $user->role !== 'owner') ? $user->branch_id : $request->branch_id;

                $totalLossValue = 0.00;
                $productNames = [];
                
                $dateCode = Carbon::parse($request->write_off_date)->format('Y/m');
                $docNumber = "WROFF/{$dateCode}/" . rand(1000, 9999); 

                $writeOffId = DB::table('stock_write_offs')->insertGetId([
                    'write_off_number' => $docNumber,
                    'branch_id' => $branchId,
                    'total_loss_value' => 0, 
                    'notes' => $request->notes,
                    'created_by' => $user->id ?? 1,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);

                foreach ($request->items as $item) {
                    $product = DB::table('products')->where('id', $item['product_id'])->first();
                    
                    // Logika penggabungan nama dan varian
                    $fullName = $product ? (strtoupper($product->name) . ($product->variant_name ? " - " . strtoupper($product->variant_name) : "")) : "ID " . $item['product_id'];
                    $productNames[] = $fullName;

                    $productName = $product ? strtoupper($product->name) : "ID " . $item['product_id'];

                    $multiplier = 1.00;
                    $selectedUnit = strtoupper($item['unit'] ?? 'PCS');
                    
                    if ($selectedUnit === strtoupper($product->buy_unit ?? '')) {
                        $multiplier = (float)($product->conversion_factor ?? 1);
                    } elseif ($selectedUnit === strtoupper($product->unit_3_name ?? '')) {
                        $multiplier = (float)($product->conversion_3_qty ?? 1);
                    } elseif ($selectedUnit === strtoupper($product->unit_4_name ?? '')) {
                        $multiplier = (float)($product->conversion_4_qty ?? 1);
                    }

                    $baseQty = (float)$item['qty'] * $multiplier;

                    $stock = DB::table('product_stocks')
                        ->where('product_id', $item['product_id'])
                        ->where('branch_id', $branchId)
                        ->lockForUpdate()
                        ->first();

                    $currentBsQty = $stock ? (float)$stock->bs_quantity : 0.00;

                    if (!$stock || $currentBsQty < $baseQty) {
                        throw new \Exception("Stok Karantina {$productName} tidak cukup! (Diminta: {$baseQty}, Tersedia di BS: {$currentBsQty})");
                    }

                    DB::table('product_stocks')->where('id', $stock->id)->update([
                        'bs_quantity' => $currentBsQty - $baseQty,
                        'updated_at' => now()
                    ]);

                    // PERBAIKAN LOGICAL BUG: Hitung Total Loss Value menggunakan Moving Average
                    $hppItem = (isset($product->average_cost) && $product->average_cost > 0) ? (float) $product->average_cost : (float) ($product->buy_price ?? 0);
                    $itemLossValue = $hppItem * $baseQty;
                    $totalLossValue += $itemLossValue;

                    DB::table('stock_write_off_items')->insert([
                        'stock_write_off_id' => $writeOffId,
                        'product_id' => $item['product_id'],
                        'qty' => $baseQty,
                        'unit' => $product->unit ?? 'PCS', 
                        'unit_price' => $hppItem, // Simpan HPP historis di baris ini
                        'source_type' => 'internal_damage',
                    ]);

                    DB::table('stock_transactions')->insert([
                        'branch_id' => $branchId,
                        'product_id' => $item['product_id'],
                        'type' => 'bs_write_off',
                        'input_quantity' => (float)$item['qty'],
                        'input_unit' => $selectedUnit,
                        'actual_quantity' => -$baseQty, 
                        'note' => "Pemusnahan BS (Write-Off): " . $docNumber,
                        'user_id' => $user->id ?? 1,
                        'created_at' => now(),
                        'updated_at' => now()
                    ]);
                }

                DB::table('stock_write_offs')->where('id', $writeOffId)->update([
                    'total_loss_value' => $totalLossValue
                ]);

                // =========================================================================
                // INTEGRASI JURNAL AKUNTANSI (STRICT GL VALIDATION)
                // =========================================================================
                if ($totalLossValue > 0) {
                    $akunBebanKerusakan = AccountingService::getAccountId('inventory_shrinkage_account'); 
                    $akunPersediaanBS = AccountingService::getAccountId('bs_inventory_account'); 

                    if (!$akunBebanKerusakan || !$akunPersediaanBS) {
                        throw new \Exception("Sistem Gagal: Master Akun Beban Kerusakan atau Persediaan BS belum dikonfigurasi di Pengaturan Akuntansi.");
                    }

                    AccountingService::log([
                        'branch_id'   => $branchId,
                        'entry_date'  => $request->write_off_date,
                        'description' => "Pemusnahan BS: " . implode(", ", array_unique($productNames)) . " - " . $docNumber,
                        'reference'   => $docNumber,
                        'source_type' => 'BS_WRITE_OFF',
                        'user_id'     => $user->id ?? 1,
                        'items'       => [
                            ['account_id' => $akunBebanKerusakan, 'debit' => $totalLossValue, 'credit' => 0],
                            ['account_id' => $akunPersediaanBS, 'debit' => 0, 'credit' => $totalLossValue]
                        ]
                    ]);
                }
                // =========================================================================

                return response()->json(['success' => true, 'message' => 'Barang rusak berhasil dimusnahkan.', 'doc_number' => $docNumber]);
            });
        } catch (\Exception $e) {
            Log::error("Write-Off BS Error: " . $e->getMessage());
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }
}