<?php

namespace App\Http\Controllers;

use App\Models\FeeChallan;
use App\Models\FeePayment;
use App\Models\Student;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;

/**
 * Annual "Fee Card" — a per-student yearly fee voucher printed in three copies
 * (Bank · School · Parent) on one A4 landscape page. Mirrors the legacy
 * fee_card.php. Billing/payment figures are drawn from the student's FAMILY
 * challans, because this system bills and collects per family.
 */
class FeeCardController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [new Middleware('permission:fees.view')];
    }

    public function show(Request $request, Student $student): View
    {
        $student->load(['family', 'schoolClass', 'section', 'branch', 'academicSession']);

        $year = (int) ($request->integer('year') ?: now()->year);
        $familyId = $student->family_id;

        // All challans for this family in the selected year (by billing month).
        $challans = FeeChallan::where('family_id', $familyId)
            ->whereYear('billing_month', $year)
            ->orderBy('billing_month')
            ->get();

        // Monthly grid: billed (total payable) and paid, per calendar month.
        $billed = array_fill(1, 12, 0.0);
        $paid = array_fill(1, 12, 0.0);
        foreach ($challans as $c) {
            $m = (int) $c->billing_month->format('n');
            $billed[$m] += $c->net_payable;
            $paid[$m] += (float) $c->paid_amount;
        }

        // Outstanding lines — what to pay now (unpaid / partial challans, any year).
        $outstanding = FeeChallan::where('family_id', $familyId)
            ->whereIn('status', ['unpaid', 'partial'])
            ->orderBy('billing_month')
            ->get();

        $lines = $outstanding->map(function ($c) {
            $period = $c->billing_month ? ' ('.$c->billing_month->format('M Y').')' : '';

            return [
                'desc' => ($c->title ?: 'Fee Challan').$period,
                'amount' => $c->balance,
            ];
        })->filter(fn ($l) => $l['amount'] > 0)->values();

        $subtotal = (float) $lines->sum('amount');
        $earliestDue = optional($outstanding->sortBy('due_date')->first())->due_date;
        $dueDate = $earliestDue ?: now();
        $validDate = $dueDate->copy()->addDays(5);

        // Voucher number — first outstanding challan number, else a generated one.
        $voucherNo = optional($outstanding->first())->challan_number
            ?: strtoupper(now()->format('M')).'-'.str_pad((string) $student->id, 5, '0', STR_PAD_LEFT).'-'.random_int(1000, 9999);

        // Distinct years this family has been billed (for the year selector).
        $years = FeeChallan::where('family_id', $familyId)
            ->selectRaw('DISTINCT YEAR(billing_month) y')
            ->orderByDesc('y')->pluck('y')->map(fn ($y) => (int) $y)->all();
        if (! in_array($year, $years, true)) {
            $years[] = $year;
            rsort($years);
        }

        // Yearly totals for the footer.
        $yearBilled = array_sum($billed);
        $yearPaid = array_sum($paid);

        return view('fees.card', compact(
            'student', 'year', 'years', 'billed', 'paid', 'lines',
            'subtotal', 'dueDate', 'validDate', 'voucherNo', 'yearBilled', 'yearPaid'
        ));
    }
}
