<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Sale;
use Carbon\Carbon;
use Illuminate\Http\Request;

class ArController extends Controller
{
    /**
     * List customers with outstanding balances, decorated with aging info.
     */
    public function index(Request $request)
    {
        $this->authorize('view-reports');

        $search  = $request->input('search');
        $bucket  = $request->input('bucket');   // 0_30 | 31_60 | 61_90 | 90_plus
        $perPage = min((int) $request->input('per_page', 20), 100);
        $today   = Carbon::today();

        $query = Customer::query()
            ->whereHas('sales', function ($q) {
                $q->where('outstanding_balance', '>', 0)
                  ->whereNotIn('status', ['returned']);
            })
            ->withSum(['sales as total_outstanding' => function ($q) {
                $q->where('outstanding_balance', '>', 0)
                  ->whereNotIn('status', ['returned']);
            }], 'outstanding_balance')
            ->with(['sales' => function ($q) {
                $q->where('outstanding_balance', '>', 0)
                  ->whereNotIn('status', ['returned'])
                  ->select('id', 'customer_id', 'sale_number', 'sale_date', 'total',
                            'amount_paid', 'outstanding_balance', 'status')
                  ->orderBy('sale_date');
            }]);

        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }

        $paginated = $query->orderByDesc('total_outstanding')->paginate($perPage);

        // Decorate each customer with aging breakdown
        $paginated->getCollection()->transform(function ($customer) use ($today) {
            $buckets    = ['0_30' => 0, '31_60' => 0, '61_90' => 0, '90_plus' => 0];
            $maxDays    = 0;
            $oldestDate = null;

            foreach ($customer->sales as $sale) {
                $days = (int) $today->diffInDays(Carbon::parse($sale->sale_date));
                if ($days > $maxDays) $maxDays = $days;
                if (!$oldestDate || Carbon::parse($sale->sale_date)->lt(Carbon::parse($oldestDate))) {
                    $oldestDate = $sale->sale_date;
                }
                $sale->days_overdue  = $days;
                $sale->aging_bucket  = $this->resolveBucket($days);
                $buckets[$this->resolveBucket($days)] += (float) $sale->outstanding_balance;
            }

            $customer->aging_buckets    = $buckets;
            $customer->oldest_sale_date = $oldestDate;
            $customer->max_days_overdue = $maxDays;

            return $customer;
        });

        // Filter by aging bucket after decoration
        if ($bucket && in_array($bucket, ['0_30', '31_60', '61_90', '90_plus'])) {
            $filtered = $paginated->getCollection()
                ->filter(fn($c) => ($c->aging_buckets[$bucket] ?? 0) > 0)
                ->values();
            $paginated->setCollection($filtered);
        }

        return response()->json($paginated);
    }

    /**
     * Global AR summary: totals and aging buckets for the Reconciliation card.
     */
    public function summary()
    {
        $this->authorize('view-reports');

        $today   = Carbon::today();
        $sales   = Sale::where('outstanding_balance', '>', 0)
                       ->whereNotIn('status', ['returned'])
                       ->select('customer_id', 'outstanding_balance', 'sale_date')
                       ->get();

        $buckets          = ['0_30' => 0, '31_60' => 0, '61_90' => 0, '90_plus' => 0];
        $totalOutstanding = 0.0;

        foreach ($sales as $sale) {
            $totalOutstanding += (float) $sale->outstanding_balance;
            $days             = (int) $today->diffInDays(Carbon::parse($sale->sale_date));
            $buckets[$this->resolveBucket($days)] += (float) $sale->outstanding_balance;
        }

        $debtorCount = $sales->whereNotNull('customer_id')
                             ->pluck('customer_id')
                             ->unique()
                             ->count();

        return response()->json([
            'total_outstanding' => $totalOutstanding,
            'debtor_count'      => $debtorCount,
            'buckets'           => $buckets,
        ]);
    }

    private function resolveBucket(int $days): string
    {
        if ($days <= 30) return '0_30';
        if ($days <= 60) return '31_60';
        if ($days <= 90) return '61_90';
        return '90_plus';
    }
}
