<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Customer;
use App\Models\Branch;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;

class AdminCustomerController extends Controller
{
    /**
     * ========================================================================
     * ALGORITMA PENILAIAN UMUR PIUTANG DINAMIS (AR AGING GRADING)
     * ========================================================================
     */
    private function _calculateCustomerGrade($customerId)
    {
        $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';                          
    }

    public function index(Request $request)
    {
        try {
            $user = $request->user();
            
            $query = Customer::with(['salesman.user', 'branch', 'district.city.province', 'customerType'])
                ->orderBy('name', 'asc');

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

            $customers = $query->get();

            // SUNTIKAN GRADE KE SETIAP DATA PELANGGAN
            foreach ($customers as $customer) {
                $customer->grade = $this->_calculateCustomerGrade($customer->id);
            }

            return response()->json([
                'success' => true,
                'data' => $customers
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false, 
                'message' => 'ERROR LARAVEL: ' . $e->getMessage(),
                'file' => $e->getFile(),
                'line' => $e->getLine()
            ], 500);
        }
    }

    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'branch_id' => 'required|exists:branches,id',
            'price_level' => 'required|in:1,2,3,4', 
            'district_id' => 'nullable|exists:districts,id',
            'customer_type_id' => 'nullable|exists:customer_types,id',
            'is_pkp' => 'boolean',
            'credit_limit_active' => 'boolean',
            'multiple_invoice_hold_active' => 'boolean',
            'default_tax_method' => 'required|in:non,include,exclude',
            'npwp' => 'nullable|string|max:30', 
            'join_date' => 'nullable|date',
            'no_ktp' => 'nullable|string|max:20',
            'ktp_photo' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', 
        ]);

        try {
            $user = $request->user();
            $data = $request->except(['ktp_photo']);
            
            if ($user && $user->role !== 'owner') {
                $data['branch_id'] = $user->branch_id;
            }
            
            if ($request->hasFile('ktp_photo')) {
                $path = $request->file('ktp_photo')->store('ktp_images', 'public');
                $data['ktp_photo_path'] = $path;
            }

            if (empty($data['customer_code'])) {
                $branch = Branch::find($data['branch_id']);
                $branchCode = isset($branch->code) ? substr(strtoupper($branch->code), 0, 2) : 'GN';
                $count = Customer::where('branch_id', $data['branch_id'])->count() + 1;
                $data['customer_code'] = $branchCode . str_pad($count, 6, '0', STR_PAD_LEFT);
            }

            if (isset($data['name'])) $data['name'] = strtoupper($data['name']);
            if (isset($data['owner_name'])) $data['owner_name'] = strtoupper($data['owner_name']);

            if (!isset($data['registration_status'])) {
                $data['registration_status'] = 'approved';
            }
            if (!isset($data['join_date'])) {
                $data['join_date'] = date('Y-m-d');
            }

            unset($data['province_id']);
            unset($data['city_id']);

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

    public function update(Request $request, $id)
    {
        $user = $request->user();
        $customer = Customer::findOrFail($id);

        if ($user && $user->role !== 'owner' && $customer->branch_id !== $user->branch_id) {
            return response()->json([
                'success' => false, 
                'message' => 'Akses ditolak: Anda tidak berhak mengubah data pelanggan dari cabang lain.'
            ], 403);
        }

        $request->validate([
            'name' => 'required|string|max:255',
            'branch_id' => 'required|exists:branches,id',
            'price_level' => 'required|in:1,2,3,4,5,6',
            'district_id' => 'nullable|exists:districts,id',
            'customer_type_id' => 'nullable|exists:customer_types,id',
            'is_pkp' => 'boolean',
            'credit_limit_active' => 'boolean',
            'multiple_invoice_hold_active' => 'boolean',
            'default_tax_method' => 'required|in:non,include,exclude',
            'npwp' => 'nullable|string|max:30',
            'join_date' => 'nullable|date',
            'no_ktp' => 'nullable|string|max:20',
            'ktp_photo' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
        ]);

        try {
            $data = $request->except(['ktp_photo']);
            
            if ($user && $user->role !== 'owner') {
                $data['branch_id'] = $user->branch_id;
            }
            
            if ($request->hasFile('ktp_photo')) {
                $path = $request->file('ktp_photo')->store('ktp_images', 'public');
                $data['ktp_photo_path'] = $path;
            }

            if (isset($data['name'])) $data['name'] = strtoupper($data['name']);
            if (isset($data['owner_name'])) $data['owner_name'] = strtoupper($data['owner_name']);

            unset($data['province_id']);
            unset($data['city_id']);

            $customer->update($data);

            return response()->json([
                'success' => true, 
                'message' => 'Data pelanggan berhasil diperbarui', 
                'data' => $customer
            ], 200);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function destroy(Request $request, $id)
    {
        try {
            $user = $request->user();
            $customer = Customer::findOrFail($id);

            if ($user && $user->role !== 'owner' && $customer->branch_id !== $user->branch_id) {
                return response()->json([
                    'success' => false, 
                    'message' => 'Akses ditolak: Anda tidak berhak menghapus pelanggan dari cabang lain.'
                ], 403);
            }

            $customer->delete();
            return response()->json(['success' => true, 'message' => 'Pelanggan berhasil dihapus'], 200);
        } catch (QueryException $e) {
            if ($e->getCode() == "23000") {
                return response()->json([
                    'success' => false, 
                    'message' => 'Gagal menghapus: Pelanggan ini sudah memiliki riwayat transaksi (Penjualan/Piutang) di sistem. Demi integritas akuntansi, silakan nonaktifkan status pelanggan ini alih-alih menghapusnya.'
                ], 400);
            }
            return response()->json(['success' => false, 'message' => 'Database Error.'], 500);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function onlineRegister(Request $request)
    {
        $request->validate([
            'shop_name' => 'required|string|max:255',
            'owner_name' => 'required|string|max:255',
            'address' => 'required|string',
        ]);

        try {
            $customer = Customer::create([
                'name' => strtoupper($request->shop_name),
                'owner_name' => strtoupper($request->owner_name),
                'address' => $request->address,
                'benchmark' => $request->benchmark,
                'latitude' => $request->latitude,
                'longitude' => $request->longitude,
                'registration_status' => 'pending',
                'is_active' => false,
                'price_level' => '1',
            ]);

            return response()->json(['success' => true, 'message' => 'Pendaftaran berhasil, menunggu verifikasi Admin.', 'data' => $customer], 201);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }

    public function approveRegistration(Request $request, $id)
    {
        try {
            $user = $request->user();
            $customer = Customer::findOrFail($id);
            
            if ($user && $user->role !== 'owner') {
                if (!empty($customer->branch_id) && $customer->branch_id !== $user->branch_id) {
                    return response()->json([
                        'success' => false, 
                        'message' => 'Akses ditolak (Security Lock): Anda mencoba memproses pendaftaran pelanggan yang sudah diplot untuk wewenang cabang lain.'
                    ], 403);
                }
            }

            $targetBranchId = ($user && $user->role === 'owner') 
                              ? ($request->branch_id ?? ($customer->branch_id ?? 1)) 
                              : ($user->branch_id ?? 1);
            
            if (empty($customer->customer_code)) {
                $branch = Branch::find($targetBranchId);
                $branchCode = isset($branch->code) ? substr(strtoupper($branch->code), 0, 2) : 'GN';
                $count = Customer::where('branch_id', $targetBranchId)->count() + 1;
                $customer->customer_code = $branchCode . str_pad($count, 6, '0', STR_PAD_LEFT);
            }

            $customer->update([
                'registration_status' => 'approved',
                'is_active' => true,
                'branch_id' => $targetBranchId,
                'salesman_id' => $request->salesman_id ?? $customer->salesman_id, 
                'district_id' => $request->district_id ?? $customer->district_id, 
                'customer_type_id' => $request->customer_type_id ?? $customer->customer_type_id,
                'credit_limit' => $request->credit_limit ?? 0,
                'price_level' => $request->price_level ?? '1',
                'is_pkp' => $request->is_pkp ?? false,
                'default_tax_method' => $request->default_tax_method ?? 'include',
                'npwp' => $request->npwp ?? $customer->npwp,
                'no_ktp' => $request->no_ktp ?? $customer->no_ktp,
                'join_date' => $request->join_date ?? ($customer->join_date ?? date('Y-m-d')),
            ]);

            return response()->json(['success' => true, 'message' => 'Toko berhasil disetujui menjadi Master Pelanggan', 'data' => $customer], 200);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
        }
    }
}