<?php

namespace App\Http\Controllers\Api;

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

class SalesmanMobileOrderController extends Controller
{
    /**
     * ========================================================================
     * FITUR BARU: AUTO-GRADING PELANGGAN BERDASARKAN UMUR PIUTANG (AR AGING)
     * ========================================================================
     */
    private function _calculateCustomerGrade($customerId)
    {
        // Tarik data 3 bulan terakhir (90 Hari)
        $threeMonthsAgo = Carbon::today()->subDays(90)->toDateString();

        $creditSales = DB::table('sales')
            ->where('customer_id', $customerId)
            ->where('payment_method', 'kredit')
            ->where('delivery_status', '!=', 'void')
            ->where('created_at', '>=', $threeMonthsAgo)
            ->get();

        if ($creditSales->isEmpty()) {
            return 'A'; 
        }

        $maxDaysToPay = 0;

        foreach ($creditSales as $sale) {
            $invoiceDate = Carbon::parse($sale->created_at);

            $lastPayment = DB::table('debt_payments')
                ->where('sale_id', $sale->id)
                ->where('payment_status', 'completed')
                ->orderBy('payment_date', 'desc')
                ->first();

            if ($sale->payment_status === 'paid' && $lastPayment) {
                $payDate = Carbon::parse($lastPayment->payment_date);
                $days = $invoiceDate->diffInDays($payDate);
            } else {
                $days = $invoiceDate->diffInDays(Carbon::today());
            }

            if ($days > $maxDaysToPay) {
                $maxDaysToPay = $days;
            }
        }

        if ($maxDaysToPay <= 30) return 'A'; 
        if ($maxDaysToPay <= 60) return 'B'; 
        if ($maxDaysToPay <= 90) return 'C'; 
        return 'D';                          
    }

    /**
     * 1. KATALOG PRODUK UNTUK SALESMAN (TERKUNCI LEVEL HARGA & MULTI-SATUAN VALID)
     */
    public function getProducts(Request $request)
    {
        $request->validate([
            'customer_id' => 'required|exists:customers,id'
        ]);

        $user = $request->user();
        $branchId = $user->branch_id;

        $customer = \App\Models\Customer::where('id', $request->customer_id)
            ->where('branch_id', $branchId)
            ->first();

        if (!$customer) {
            return response()->json(['success' => false, 'message' => 'Akses ditolak: Pelanggan tidak ditemukan di wilayah cabang Anda.'], 403);
        }
        
        preg_match('/\d+/', $customer->price_level ?? '1', $matches);
        $customerLevel = isset($matches[0]) ? (int)$matches[0] : 1;

        $products = \App\Models\Product::with([
            'category',
            'prices', 
            'stocks' => function($query) use ($branchId) {
                $query->where('branch_id', $branchId);
            }
        ])
        ->where('is_active', 1)
        ->whereIn('product_type', ['trading', 'finished_good'])
        ->where(function($query) {
            $query->whereNotNull('variant_group_id')
                  ->orWhere('buy_price', '>', 0);
        })
        ->get();

        $formattedProducts = [];

        foreach ($products as $product) {
            $stockAmount = 0;
            $reservedAmount = 0;
            if ($product->stocks && count($product->stocks) > 0) {
                foreach ($product->stocks as $s) {
                    $stockAmount += (float) ($s->quantity ?? $s->qty ?? 0);
                    $reservedAmount += (float) ($s->reserved_qty ?? 0);
                }
            } else {
                $stockAmount = (float) ($product->stock_qty ?? 0);
                $reservedAmount = (float) ($product->reserved_qty ?? 0);
            }
            $availableStock = max(0, $stockAmount - $reservedAmount); // Stok Asli (Terkecil)

            // ================================================================
            // LOGIKA ENTERPRISE: TAMPILAN STOK MENGGUNAKAN SATUAN LEVEL 2
            // ================================================================
            $hasLevel2 = !empty($product->buy_unit) || !empty($product->satuan_besar);
            $convFactor = (float) ($product->conversion_factor ?? 1);
            if ($convFactor <= 0) $convFactor = 1;

            if ($hasLevel2 && $convFactor > 1) {
                $displayStock = floor($availableStock / $convFactor);
                $displayUnit = strtoupper(trim($product->buy_unit ?? $product->satuan_besar ?? ''));
            } else {
                $displayStock = $availableStock;
                $displayUnit = strtoupper(trim($product->satuan_dasar ?? $product->unit ?? 'PCS'));
            }

            $validPrices = [];
            if ($product->prices && count($product->prices) > 0) {
                foreach ($product->prices as $p) {
                    preg_match('/\d+/', $p->level ?? '1', $pMatches);
                    $priceLevelNum = isset($pMatches[0]) ? (int)$pMatches[0] : 1;

                    if ($priceLevelNum === $customerLevel) {
                        
                        $resolvedUnitName = $p->unit_name;
                        $uLevel = (int) ($p->unit_level ?? 1);
                        $convQty = 1; // Default Pengali Base

                        if (empty($resolvedUnitName)) {
                            if ($uLevel === 2) $resolvedUnitName = $product->buy_unit ?? $product->satuan_besar ?? 'DUS';
                            elseif ($uLevel === 3) $resolvedUnitName = $product->unit_3_name ?? $product->satuan_l3 ?? 'BAL';
                            elseif ($uLevel === 4) $resolvedUnitName = $product->unit_4_name ?? $product->satuan_l4 ?? 'TRUK';
                            else $resolvedUnitName = $product->satuan_dasar ?? $product->unit ?? 'PCS';
                        }

                        // Tentukan rasio konversi harga ini terhadap satuan terkecil
                        if ($uLevel === 2) $convQty = (float)($product->conversion_factor ?? 1);
                        elseif ($uLevel === 3) $convQty = (float)($product->conversion_3_qty ?? 1);
                        elseif ($uLevel === 4) $convQty = (float)($product->conversion_4_qty ?? 1);
                        if ($convQty <= 0) $convQty = 1;

                        $validPrices[] = [
                            'id' => $product->id,
                            'unit_level' => $p->unit_level ?? '1',
                            'unit_name' => strtoupper(trim($resolvedUnitName)),
                            'min_qty' => (int) ($p->min_qty ?? 1),
                            'price' => (float) $p->amount,
                            'conversion_qty' => $convQty // PENTING UNTUK FLUTTER
                        ];
                    }
                }
            }

            if (empty($validPrices)) {
                $validPrices[] = [
                    'id' => $product->id,
                    'unit_level' => '1',
                    'unit_name' => strtoupper(trim($product->satuan_dasar ?? $product->unit ?? 'PCS')),
                    'min_qty' => 1,
                    'price' => (float) ($product->price ?? 0),
                    'conversion_qty' => 1
                ];
            }

            $formattedProducts[] = [
                'id' => $product->id,
                'name' => $product->name,
                'variant_group_id' => $product->variant_group_id,
                'variant_name' => $product->variant_name ?? '',
                'category' => $product->category ? $product->category->name : 'Umum',
                'category_id' => $product->category_id ?? 0,
                'image_url' => $product->image_path ? asset('storage/' . $product->image_path) : null,
                'available_stock' => $availableStock, // Stok terkecil asli (untuk validasi murni)
                'display_stock' => $displayStock,     // Stok level 2 (untuk tampilan layar)
                'display_unit' => $displayUnit,       // Nama satuan level 2
                'base_unit' => $product->satuan_dasar ?? $product->unit ?? 'PCS',
                'price_reference_level' => (int) ($product->price_reference_level ?? 1), // <--- PENAMBAHAN ACUAN JUAL
                'prices' => $validPrices,
            ];
        }

        return response()->json([
            'success' => true,
            'customer_info' => [
                'id' => $customer->id,
                'name' => $customer->name,
                'level' => $customerLevel,
                'credit_limit' => (float) $customer->credit_limit
            ],
            'data' => $formattedProducts
        ], 200);
    }

    /**
     * 2. TARIK PROMO AKTIF BERDASARKAN OUTLET
     */
    public function getActivePromos(Request $request)
    {
        $request->validate([
            'customer_id' => 'required|exists:customers,id'
        ]);

        $user = $request->user();

        $customer = Customer::where('id', $request->customer_id)
            ->where('branch_id', $user->branch_id)
            ->first();

        if (!$customer) {
            return response()->json(['success' => false, 'message' => 'Akses ditolak: Pelanggan bukan dari wilayah cabang Anda.'], 403);
        }

        $today = Carbon::today()->toDateString();

        $activePrograms = SalesProgram::with(['category', 'product'])
            ->where('is_active', 1)
            ->where('start_date', '<=', $today)
            ->where('end_date', '>=', $today)
            ->get();

        $programIds = $activePrograms->pluck('id');
        $allTiers = DB::table('sales_program_tiers')
            ->leftJoin('products', 'sales_program_tiers.bonus_product_id', '=', 'products.id')
            ->whereIn('sales_program_tiers.sales_program_id', $programIds)
            ->select('sales_program_tiers.*', 'products.name as bonus_product_name', 'products.unit as bonus_base_unit')
            ->get()
            ->groupBy('sales_program_id');

        $activePrograms->transform(function ($program) use ($allTiers) {
            $program->tiers = $allTiers->get($program->id, []);
            return $program;
        });

        $filteredPrograms = $activePrograms->filter(function ($program) use ($customer) {
            $level = (string) $customer->price_level;
            
            if (!empty($program->target_customer_levels)) {
                $levels = is_array($program->target_customer_levels) ? $program->target_customer_levels : json_decode($program->target_customer_levels, true);
                if (is_array($levels) && !in_array($level, $levels)) {
                    return false; 
                }
            }

            if (!empty($program->target_customer_types)) {
                $types = is_array($program->target_customer_types) ? $program->target_customer_types : json_decode($program->target_customer_types, true);
                if (is_array($types) && !in_array($customer->customer_type_id, $types)) {
                    return false; 
                }
            }

            return true; 
        })->values();

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

    /**
     * 3. SUBMIT DRAFT SALES ORDER
     */
    public function storeOrder(Request $request)
    {
        $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'visit_id' => 'nullable',
            'payment_type' => 'required|in:tunai,kredit',
            'items' => 'required|array|min:1',
            'items.*.product_id' => 'required|exists:products,id',
            'items.*.unit_name' => 'required|string',
            'items.*.qty' => 'required|numeric|min:0.1',
            'items.*.price' => 'required|numeric|min:0',
            'items.*.is_free_item' => 'nullable|boolean',
            'items.*.discount_nominal' => 'nullable|numeric|min:0',
            'items.*.applied_program_id' => 'nullable|exists:sales_programs,id',
        ]);

        $user = $request->user();
        $branchId = $user->branch_id;

        $salesmanDetail = null;
        if ($user->role === 'salesman') {
            $salesmanDetail = DB::table('salesmen')->where('user_id', $user->id)->first();
            if ($salesmanDetail && $salesmanDetail->salesman_type === 'CANVAS') {
                return response()->json([
                    'success' => false, 
                    'message' => 'Akses ditolak. Sales Canvas harus menggunakan modul transaksi langsung (Bukan Draft SO).'
                ], 403);
            }
        }

        $customer = Customer::where('id', $request->customer_id)
            ->where('branch_id', $branchId)
            ->first();

        if (!$customer) {
            return response()->json(['success' => false, 'message' => 'Akses ditolak: Pelanggan tidak terdaftar di wilayah cabang Anda.'], 403);
        }

        $targetSalesmanId = null;
        if ($user->role === 'supervisor_sales') {
            $targetSalesmanId = $customer->salesman_id;
        } else {
            $targetSalesmanId = $salesmanDetail ? $salesmanDetail->id : $customer->salesman_id;
        }

        try {
            DB::beginTransaction();

            $subtotalKotor = 0;
            $totalDiscountAmount = 0;
            $processedItems = [];

            foreach ($request->items as $item) {
                $product = \App\Models\Product::find($item['product_id']);
                
                $multiplier = 1;
                $uName = strtoupper(trim($item['unit_name']));
                if ($uName === strtoupper(trim($product->buy_unit ?? $product->satuan_besar ?? ''))) $multiplier = $product->conversion_factor ?? 1;
                elseif ($uName === strtoupper(trim($product->unit_3_name ?? $product->satuan_l3 ?? ''))) $multiplier = $product->conversion_3_qty ?? 1;
                elseif ($uName === strtoupper(trim($product->unit_4_name ?? $product->satuan_l4 ?? ''))) $multiplier = $product->conversion_4_qty ?? 1;

                $totalBaseQty = (float)$item['qty'] * (float)$multiplier;
                
                $stockRecord = DB::table('product_stocks')->where('branch_id', $branchId)->where('product_id', $product->id)->first();
                $avail = $stockRecord ? ((float)$stockRecord->quantity - (float)$stockRecord->reserved_qty) : 0;

                if ($avail < $totalBaseQty) {
                    throw new \Exception("Stok {$product->name} tidak mencukupi. Sisa Base Unit: {$avail}");
                }

                $isFreeItem = isset($item['is_free_item']) ? (int)$item['is_free_item'] : 0;
                $discountNominal = isset($item['discount_nominal']) ? (float)$item['discount_nominal'] : 0;
                $appliedProgramId = isset($item['applied_program_id']) ? $item['applied_program_id'] : null;

                $itemPrice = $isFreeItem ? 0 : (float)$item['price'];
                
                $itemTotal = ($itemPrice - $discountNominal) * (float)$item['qty'];
                if ($itemTotal < 0) $itemTotal = 0;

                $subtotalKotor += ($itemPrice * (float)$item['qty']); 
                $totalDiscountAmount += ($discountNominal * (float)$item['qty']);

                $processedItems[] = [
                    'product_id' => $product->id,
                    'unit_name' => $item['unit_name'],
                    'qty' => $item['qty'],
                    'price' => $itemPrice,
                    'discount_nominal' => $discountNominal,
                    'total_price' => $itemTotal,
                    'is_free_item' => $isFreeItem,
                    'applied_program_id' => $appliedProgramId,
                    'total_base_qty' => $totalBaseQty
                ];
            }

            $grandTotal = $subtotalKotor - $totalDiscountAmount;

            $orderStatus = 'pending'; 
            $catatanKredit = '';

            // ========================================================================
            // PENAMBAHAN: GATEWAY PENGECEKAN LIMIT KREDIT & AUTO-GRADING UNTUK SALES TO
            // ========================================================================
            if ($request->payment_type === 'kredit') {
                $limit = (float) $customer->credit_limit;
                
                if ($limit <= 0) {
                    throw new \Exception("Gagal! Pelanggan tidak memiliki plafon kredit (Limit: Rp 0). Transaksi kredit tidak diizinkan.");
                }

                $creditCheck = \App\Models\SalesOrder::checkCreditHold($customer->id, $grandTotal);
                
                // Minta bantuan mesin Auto-Grading
                $grade = $this->_calculateCustomerGrade($customer->id);
                $isGradeHold = in_array($grade, ['B', 'C', 'D']); 

                if ($creditCheck['is_hold'] || $isGradeHold) {
                    $orderStatus = \App\Models\SalesOrder::STATUS_CREDIT_HOLD ?? 'credit_hold';
                    
                    $reasons = [];
                    if ($creditCheck['is_hold']) $reasons[] = $creditCheck['message'];
                    if ($isGradeHold) $reasons[] = "Pelanggan Grade $grade (Ada histori telat bayar > 30 hari dalam 3 bln terakhir)";
                    
                    $catatanKredit = "\n[" . implode(" | ", $reasons) . "]";
                }
            }

            $soNumber = 'SO-SLS-' . date('Ymd') . '-' . rand(1000, 9999);
            
            $soId = DB::table('sales_orders')->insertGetId([
                'so_number' => $soNumber,
                'branch_id' => $branchId,
                'fulfillment_branch_id' => $branchId,
                'customer_id' => $customer->id,
                'salesman_id' => $targetSalesmanId, 
                'user_id' => $user->id,
                'customer_name' => $customer->name,
                'customer_phone' => $customer->phone ?? '',
                'shipping_address' => $customer->address,
                'subtotal' => $subtotalKotor,
                'shipping_fee' => 0,
                'discount_amount' => $totalDiscountAmount, 
                'grand_total' => $grandTotal,
                'payment_method' => $request->payment_type,
                'status' => $orderStatus, 
                'note' => ($orderStatus === 'credit_hold' ? 'Order via Aplikasi Sales TO (Ditahan - Menunggu Otorisasi Pusat)' : 'Order via Aplikasi Sales TO') . $catatanKredit,
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now(),
            ]);

            foreach ($processedItems as $pItem) {
                DB::table('sales_order_items')->insert([
                    'sales_order_id' => $soId,
                    'product_id' => $pItem['product_id'],
                    'unit_name' => $pItem['unit_name'],
                    'qty' => $pItem['qty'],
                    'price' => $pItem['price'],
                    'discount_nominal' => $pItem['discount_nominal'],
                    'total_price' => $pItem['total_price'],
                    'is_free_item' => $pItem['is_free_item'],
                    'applied_program_id' => $pItem['applied_program_id'], 
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now()
                ]);

                DB::table('product_stocks')
                    ->where('branch_id', $branchId)
                    ->where('product_id', $pItem['product_id'])
                    ->update([
                        'reserved_qty' => DB::raw("reserved_qty + " . $pItem['total_base_qty'])
                    ]);
            }

            if ($request->filled('visit_id')) {
                DB::table('salesman_visits')->where('id', $request->visit_id)->update([
                    'visit_result' => 'order',
                    'updated_at' => Carbon::now()
                ]);
            }

            DB::commit();

            $responseMessage = $orderStatus === 'credit_hold' 
                ? 'PERINGATAN: Pelanggan Grade Berisiko atau OVERLIMIT. Draft SO tertahan untuk otorisasi pusat.' 
                : 'Pesanan + Promo berhasil dikirim ke antrean Gudang!';

            return response()->json([
                'success' => true,
                'message' => $responseMessage,
                'data' => [
                    'so_number' => $soNumber,
                    'grand_total' => $grandTotal,
                    'status' => $orderStatus
                ]
            ], 201);

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

    public function getSalesmanOrderHistory(Request $request)
    {
        $user = $request->user();
        
        $query = DB::table('sales_orders')
            ->whereDate('created_at', Carbon::today()->toDateString());

        if ($user->role === 'supervisor_sales') {
            $bawahanIds = DB::table('salesmen')->where('supervisor_id', $user->id)->pluck('id')->toArray();
            
            if (!empty($bawahanIds)) {
                $query->whereIn('salesman_id', $bawahanIds);
            } else {
                $query->where('user_id', $user->id); 
            }
        } else {
            $query->where('user_id', $user->id);
        }

        $orders = $query->orderBy('created_at', 'desc')
            ->get()
            ->map(function($order) {
                return [
                    'id' => $order->id,
                    'so_number' => $order->so_number,
                    'customer_name' => $order->customer_name,
                    'grand_total' => (float) $order->grand_total,
                    'payment_method' => $order->payment_method,
                    'status' => $order->status, 
                ];
            });

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