<?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 StockAdjustmentController extends Controller
{
    /**
     * MENDAPATKAN DATA UNTUK LEMBAR KERJA OPNAME
     */
    public function getWorksheet(Request $request)
    {
        try {
            $user = auth()->user();
            
            // PERBAIKAN ENTERPRISE: Isolasi Paksa Cabang (IDOR Protection)
            $branchId = ($user && $user->role !== 'owner') ? $user->branch_id : $request->query('branch_id');
            
            if (!$branchId) throw new \Exception("Pilih gudang terlebih dahulu.");

            $products = DB::table('products as p')
                ->leftJoin('product_stocks as ps', function($join) use ($branchId) {
                    $join->on('p.id', '=', 'ps.product_id')
                         ->where('ps.branch_id', '=', $branchId);
                })
                ->select(
                    'p.id as product_id', 'p.sku', 'p.name as product_name', 'p.variant_name', 
                    'p.unit as base_unit', 'p.buy_price', 'p.average_cost',
                    'p.buy_unit', 'p.conversion_factor',
                    'p.unit_3_name', 'p.conversion_3_qty',
                    'p.unit_4_name', 'p.conversion_4_qty',
                    'ps.quantity as system_qty'
                )
                ->where('p.is_active', 1)
                ->orderBy('p.name', 'asc')
                ->get();

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

    /**
     * EKSEKUSI PENYESUAIAN STOK & JURNAL
     */
    public function store(Request $request)
    {
        $request->validate([
            'branch_id' => 'required',
            'adjustment_date' => 'required|date',
            'notes' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required',
            'items.*.actual_qty' => 'required|numeric|min:0',
            'items.*.selected_unit' => 'required|string', 
        ]);

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

                $totalSurplusValue = 0.00;
                $totalDeficitValue = 0.00;
                
                $dateCode = Carbon::parse($request->adjustment_date)->format('Y/m');
                $docNumber = "ADJ/{$dateCode}/" . rand(1000, 9999); 

                $adjId = DB::table('stock_adjustments')->insertGetId([
                    'adjustment_number' => $docNumber,
                    'branch_id' => $branchId,
                    'adjustment_date' => $request->adjustment_date,
                    'total_surplus_value' => 0,
                    'total_deficit_value' => 0,
                    'notes' => $request->notes,
                    'created_by' => $user->id ?? 1,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);

                $productDetails = [];
                foreach ($request->items as $item) {
                    $product = DB::table('products')->where('id', $item['product_id'])->first();
                    $fullName = $product ? (strtoupper($product->name) . ($product->variant_name ? " - " . strtoupper($product->variant_name) : "")) : "ID " . $item['product_id'];
                    $productDetails[] = $fullName;
                    
                    // Gunakan Moving Average Cost (HPP Rata-Rata) untuk valuasi
                    $unitPrice = (isset($product->average_cost) && $product->average_cost > 0) 
                                 ? (float) $product->average_cost 
                                 : (float) ($product->buy_price ?? 0);

                    // ==========================================================
                    // TRANSLATOR SATUAN (Ubah Karton/Dus kembali ke Botol/Pcs)
                    // ==========================================================
                    $multiplier = 1.00;
                    $selectedUnit = strtoupper($item['selected_unit']);
                    
                    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);
                    }

                    // Base Qty adalah Hasil Fisik yang sudah dikalikan faktor (Misal: 10 Karton x 24 = 240 Botol)
                    $actualBaseQty = (float)$item['actual_qty'] * $multiplier;

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

                    $systemQty = $stock ? (float)$stock->quantity : 0.00;
                    
                    // Bandingkan semuanya menggunakan Satuan Dasar (Botol/Pcs)
                    $variance = $actualBaseQty - $systemQty;

                    if ($variance == 0) continue; 

                    $varianceType = $variance > 0 ? 'surplus' : 'deficit';
                    $varianceValue = abs($variance) * $unitPrice;

                    if ($varianceType === 'surplus') {
                        $totalSurplusValue += $varianceValue;
                    } else {
                        $totalDeficitValue += $varianceValue;
                    }

                    if ($stock) {
                        DB::table('product_stocks')->where('id', $stock->id)->update(['quantity' => $actualBaseQty, 'updated_at' => now()]);
                    } else {
                        DB::table('product_stocks')->insert([
                            'product_id' => $item['product_id'], 'branch_id' => $branchId, 
                            'quantity' => $actualBaseQty, 'created_at' => now(), 'updated_at' => now()
                        ]);
                    }

                    DB::table('stock_adjustment_items')->insert([
                        'stock_adjustment_id' => $adjId,
                        'product_id' => $item['product_id'],
                        'system_qty' => $systemQty,
                        'actual_qty' => $actualBaseQty, 
                        'variance_qty' => $variance,
                        'unit' => $product->unit ?? 'PCS', 
                        'unit_price' => $unitPrice,
                        'variance_type' => $varianceType,
                    ]);

                    DB::table('stock_transactions')->insert([
                        'branch_id' => $branchId,
                        'product_id' => $item['product_id'],
                        'type' => 'stock_adjustment',
                        'input_quantity' => (float)$item['actual_qty'],
                        'input_unit' => $selectedUnit,
                        'actual_quantity' => $variance, 
                        'note' => "Opname " . strtoupper($varianceType) . " (Sistem: $systemQty, Fisik: $actualBaseQty) - $docNumber",
                        'user_id' => $user->id ?? 1,
                        'created_at' => now(),
                        'updated_at' => now()
                    ]);
                }

                DB::table('stock_adjustments')->where('id', $adjId)->update([
                    'total_surplus_value' => $totalSurplusValue,
                    'total_deficit_value' => $totalDeficitValue
                ]);

                // ==========================================================
                // EKSEKUSI JURNAL AKUNTANSI VIA ACCOUNTING SERVICE (STRICT GL)
                // ==========================================================
                if ($totalSurplusValue > 0 || $totalDeficitValue > 0) {
                    
                    $akunPersediaan = AccountingService::getAccountId('inventory_account');  
                    $akunBebanSelisih = AccountingService::getAccountId('inventory_shrinkage_account'); 
                    $akunPendapatanLain = AccountingService::getAccountId('other_income_account'); 

                    if (!$akunPersediaan || (!$akunBebanSelisih && $totalDeficitValue > 0) || (!$akunPendapatanLain && $totalSurplusValue > 0)) {
                        throw new \Exception("Sistem Gagal: Master Akun Selisih Stok / Persediaan belum dikonfigurasi di Pengaturan Akuntansi.");
                    }

                    $journalItems = [];

                    // 1. Jurnal untuk Barang Kurang (Beban bertambah, Persediaan Berkurang)
                    if ($totalDeficitValue > 0) {
                        $journalItems[] = ['account_id' => $akunBebanSelisih, 'debit' => $totalDeficitValue, 'credit' => 0];
                        $journalItems[] = ['account_id' => $akunPersediaan, 'debit' => 0, 'credit' => $totalDeficitValue];
                    }

                    // 2. Jurnal untuk Barang Berlebih (Persediaan Bertambah, Pendapatan Lain-lain Bertambah)
                    if ($totalSurplusValue > 0) {
                        $journalItems[] = ['account_id' => $akunPersediaan, 'debit' => $totalSurplusValue, 'credit' => 0];
                        $journalItems[] = ['account_id' => $akunPendapatanLain, 'debit' => 0, 'credit' => $totalSurplusValue];
                    }

                    AccountingService::log([
                        'branch_id'   => $branchId,
                        'entry_date'  => $request->adjustment_date,
                        'description' => "Penyesuaian: " . implode(", ", array_unique($productDetails)) . " - " . $docNumber,
                        'reference'   => $docNumber,
                        'source_type' => 'STOCK_ADJUSTMENT',
                        'user_id'     => $user->id ?? 1,
                        'items'       => $journalItems
                    ]);
                }
                // ==========================================================

                return response()->json(['success' => true, 'message' => 'Opname berhasil diproses dan dijurnal.', 'doc_number' => $docNumber]);
            });
        } catch (\Exception $e) {
            Log::error("Stock Adjustment Error: " . $e->getMessage());
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }
}