<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Entry;
use App\Models\Order;
use App\Models\Installment;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AdminAccountController extends Controller
{
    /**
     * 🚀 1. Get dashboard entries
     */
    public function getDashboardData()
    {
        $entries = Entry::withCount('installments')
                        ->orderBy('id', 'desc')
                        ->get();

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

    /**
     * 🚀 2. Get available consolidated orders
     */
    public function getAvailableOrders()
    {
        $orders = Order::whereDoesntHave('entries')
                       ->orderBy('id', 'desc')
                       ->get();

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

    /**
     * 🚀 3. Create new entry
     */
    public function accountCreateOrder(Request $request)
    {
        $data = $request->validate([
            'description'      => 'required|string|max:255',
            'region'           => 'required|string|max:50',
            'amount'           => 'required|numeric|min:1',
            'entry_date'       => 'nullable|date',
            'selected_orders'  => 'nullable|array',
            'selected_orders.*'=> 'integer|exists:orders,id',
        ]);

        return DB::transaction(function () use ($data) {

            $entryDate = $data['entry_date'] ?? now()->toDateString();

            // Count selected consolidated orders
            $orderQuantity = !empty($data['selected_orders'])
                           ? count($data['selected_orders'])
                           : 0;

            // Generate entry No: PAY-2025-001
            $prefix = 'PAY-' . date('Y') . '-';
            $last = Entry::where('entry_no', 'like', $prefix . '%')
                         ->orderBy('id', 'desc')
                         ->first();

            $next = $last
                  ? intval(substr($last->entry_no, strrpos($last->entry_no, '-') + 1)) + 1
                  : 1;

            $entryNo = $prefix . str_pad($next, 7, '0', STR_PAD_LEFT);

            // Create entry
            $entry = Entry::create([
                'entry_no'        => $entryNo,
                'description'     => $data['description'],
                'region'          => $data['region'],
                'order_quantity'  => $orderQuantity,
                'amount'          => $data['amount'],
                'pending_amount'  => $data['amount'],
                'entry_date'      => $entryDate,
                'payment_status'  => 'unpaid',
                'toggle_pos'      => 0,
                'dispatch_status' => 'pending',
            ]);

            // Attach consolidated orders
            if (!empty($data['selected_orders'])) {
                $entry->orders()->attach($data['selected_orders']);
            }

            $entry->load('orders');

            return response()->json([
                'success' => true,
                'message' => 'Entry Created Successfully',
                'entry'   => $entry
            ], 201);
        });
    }

    /**
     * 🚀 4. Toggle payment switch
     */
    public function togglePayment(Request $request)
    {
        $request->validate([
            'entry_no'   => 'required|string|exists:entries,entry_no',
            'toggle_pos' => 'required|integer|in:0,1,2',
        ]);

        $entry = Entry::where('entry_no', $request->entry_no)->firstOrFail();

        $map = [
            0 => 'unpaid',
            1 => 'pending',
            2 => 'paid'
        ];

        $entry->update([
            'toggle_pos'      => $request->toggle_pos,
            'payment_status'  => $map[$request->toggle_pos],
        ]);

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

    /**
     * 🚀 5. Add Installment
     */
    public function addInstallment(Request $request)
    {
        $data = $request->validate([
            'entry_no'  => 'required|exists:entries,entry_no',
            'proc_date' => 'nullable|date',
            'amount'    => 'required|numeric|min:1',
            'status'    => 'required|string'
        ]);

        return DB::transaction(function () use ($data) {

            $entry = Entry::where('entry_no', $data['entry_no'])
                          ->lockForUpdate()
                          ->firstOrFail();

            $amount = floatval($data['amount']);

            if ($amount > $entry->pending_amount) {
                return response()->json([
                    'success' => false,
                    'message' => 'Installment cannot exceed pending amount.'
                ], 422);
            }

            $installment = Installment::create([
                'entry_id'   => $entry->id,
                'proc_date'  => $data['proc_date'] ?? now()->toDateString(),
                'amount'     => $amount,
                'description'=> $entry->description,
                'region'     => $entry->region,
                'status'     => $data['status']
            ]);

            $entry->pending_amount -= $amount;

            if ($entry->pending_amount <= 0.001) {
                $entry->pending_amount = 0;
                $entry->dispatch_status = 'dispatched';
            }

            $entry->save();

            return response()->json([
                'success'     => true,
                'entry'       => $entry,
                'installment' => $installment
            ]);
        });
    }

    /**
 * 🚀 6. Update Installment Status
 */
    public function updateInstallmentStatus(Request $request)
    {
        $data = $request->validate([
            'installment_id' => 'required|exists:installments,id',
            'status'         => 'required|string|max:50'
        ]);

        return DB::transaction(function () use ($data) {

            $installment = Installment::lockForUpdate()->findOrFail($data['installment_id']);

            $installment->status = $data['status'];
            $installment->save();

            $entry = Entry::lockForUpdate()->find($installment->entry_id);

            // If ANY installment is not delivered — entry is NOT delivered
            if ($entry->installments()->where('status', '!=', 'Delivered')->exists()) {
                // entry still in progress
                $entry->dispatch_status = 'pending';
            } else {
                // all installments delivered
                $entry->dispatch_status = 'delivered';
            }

            $entry->save();

            return response()->json([
                'success' => true,
                'message' => 'Installment updated successfully',
                'installment' => $installment,
                'entry' => $entry
            ]);
        });
    }


    /**
     * 🚀 6. Entry Details (installment history)
     */
    public function getEntryDetails($entry_no)
    {
        $entry = Entry::with('installments')
                      ->where('entry_no', $entry_no)
                      ->firstOrFail();

        $totalProcessed = $entry->amount - $entry->pending_amount;

        return response()->json([
            'success'         => true,
            'entry'           => $entry,
            'total_processed' => $totalProcessed,
            'pending'         => $entry->pending_amount,
        ]);
    }
}
