<?php

namespace App\Services\Payroll;

use App\Models\Employee;
use App\Models\PayComponent;
use App\Models\PayrollRun;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

/**
 * Turns a calculated payroll run into report matrices: the wide Payroll
 * Register (per structure), the bank payment schedule and statutory schedules.
 * Pivots the normalised payslip_lines back into the familiar column layout.
 */
class ReportBuilder
{
    /** @return array<int,string> distinct salary structures present in the run */
    public function structures(PayrollRun $run): array
    {
        return $run->payslips()
            ->whereNotNull('salary_structure')
            ->distinct()
            ->orderBy('salary_structure')
            ->pluck('salary_structure')
            ->all();
    }

    /**
     * Wide register for one structure.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>, component_codes: array<int,string>}
     */
    public function register(PayrollRun $run, string $structure): array
    {
        $order = PayComponent::pluck('display_order', 'code');

        $payslips = $run->payslips()
            ->where('salary_structure', $structure)
            ->with('lines')
            ->orderBy('employee_code')
            ->get();

        // Discover which components actually appear for this structure.
        $earn = [];      // code => name
        $deduct = [];    // code => name  (DEDUCTION + STATUTORY)
        foreach ($payslips as $slip) {
            foreach ($slip->lines as $line) {
                if ($line->type === PayComponent::TYPE_EARNING) {
                    $earn[$line->code] = $line->name;
                } else {
                    $deduct[$line->code] = $line->name;
                }
            }
        }
        $sortByOrder = fn (array $map) => collect($map)
            ->sortBy(fn ($name, $code) => $order[$code] ?? 9999)
            ->all();
        $earn = $sortByOrder($earn);
        $deduct = $sortByOrder($deduct);

        $headings = array_merge(
            ['S/N', 'File Number', 'IPPIS Number', 'Name', 'Grade', 'Step', 'Department'],
            array_values($earn),
            ['TOTAL GROSS'],
            array_values($deduct),
            ['TOTAL DEDUCTIONS', 'NET PAY'],
        );

        $rows = [];
        $sn = 0;
        foreach ($payslips as $slip) {
            $amounts = $slip->lines->keyBy('code')->map(fn ($l) => (float) $l->amount);

            $row = [
                ++$sn,
                $slip->file_number,
                $slip->employee_code,
                $slip->full_name,
                $slip->grade_level,
                $slip->salary_step,
                $slip->department_name,
            ];
            foreach (array_keys($earn) as $code) {
                $row[] = $this->num($amounts[$code] ?? null);
            }
            $row[] = $this->num($slip->gross);
            foreach (array_keys($deduct) as $code) {
                $row[] = $this->num($amounts[$code] ?? null);
            }
            $row[] = $this->num($slip->total_deductions);
            $row[] = $this->num($slip->net_pay);

            $rows[] = $row;
        }

        return [
            'headings' => $headings,
            'rows' => $rows,
            'component_codes' => array_merge(array_keys($earn), array_keys($deduct)),
        ];
    }

    /**
     * Cross-structure summary: one row per structure with headline totals.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>}
     */
    public function registerSummary(PayrollRun $run): array
    {
        $rows = [];
        $grand = ['emp' => 0, 'gross' => 0.0, 'stat' => 0.0, 'vol' => 0.0, 'ded' => 0.0, 'net' => 0.0];

        foreach ($this->structures($run) as $structure) {
            $agg = $run->payslips()->where('salary_structure', $structure)
                ->selectRaw('COUNT(*) c, SUM(gross) g, SUM(statutory_deductions) s, SUM(voluntary_deductions) v, SUM(total_deductions) d, SUM(net_pay) n')
                ->first();

            $rows[] = [
                $structure,
                (int) $agg->c,
                $this->num($agg->g),
                $this->num($agg->s),
                $this->num($agg->v),
                $this->num($agg->d),
                $this->num($agg->n),
            ];
            $grand['emp'] += (int) $agg->c;
            $grand['gross'] += (float) $agg->g;
            $grand['stat'] += (float) $agg->s;
            $grand['vol'] += (float) $agg->v;
            $grand['ded'] += (float) $agg->d;
            $grand['net'] += (float) $agg->n;
        }

        $rows[] = [
            'TOTAL', $grand['emp'], $this->num($grand['gross']), $this->num($grand['stat']),
            $this->num($grand['vol']), $this->num($grand['ded']), $this->num($grand['net']),
        ];

        return [
            'headings' => ['Structure', 'Employees', 'Gross', 'Statutory', 'Voluntary', 'Total Deductions', 'Net Pay'],
            'rows' => $rows,
        ];
    }

    /**
     * Bank payment schedule, sorted by bank then account name.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>}
     */
    public function bankSchedule(PayrollRun $run): array
    {
        $payslips = $run->payslips()
            ->orderBy('bank_name')
            ->orderBy('full_name')
            ->get();

        $rows = [];
        $sn = 0;
        $total = 0.0;
        foreach ($payslips as $slip) {
            $rows[] = [
                ++$sn,
                $slip->bank_name ?: '(none)',
                $slip->account_number,
                $slip->full_name,
                $slip->file_number,
                $this->num($slip->net_pay),
            ];
            $total += (float) $slip->net_pay;
        }
        $rows[] = ['', '', '', '', 'TOTAL', $this->num($total)];

        return [
            'headings' => ['S/N', 'Bank', 'Account Number', 'Account Name', 'File Number', 'Net Pay'],
            'rows' => $rows,
        ];
    }

    /**
     * Statutory schedule for a component code (income_tax | pension | nhf).
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>, title: string}
     */
    public function statutory(PayrollRun $run, string $code): array
    {
        $withPension = $code === 'pension';

        $payslips = $run->payslips()
            ->whereHas('lines', fn ($q) => $q->where('code', $code))
            ->with(['lines' => fn ($q) => $q->where('code', $code)])
            ->orderBy('employee_code')
            ->get();

        $headings = ['S/N', 'File Number', 'Name'];
        if ($withPension) {
            $headings[] = 'PFA';
            $headings[] = 'RSA PIN';
        }
        $headings = array_merge($headings, ['Base', 'Amount']);

        $rows = [];
        $sn = 0;
        $total = 0.0;
        foreach ($payslips as $slip) {
            $line = $slip->lines->first();
            if (! $line) {
                continue;
            }
            $row = [++$sn, $slip->employee_code, $slip->full_name];
            if ($withPension) {
                $row[] = $slip->pension_house;
                $row[] = $slip->pen_number;
            }
            $row[] = $this->num($line->base);
            $row[] = $this->num($line->amount);
            $rows[] = $row;
            $total += (float) $line->amount;
        }
        // Total row padded to heading width.
        $totalRow = array_fill(0, count($headings), '');
        $totalRow[count($headings) - 2] = 'TOTAL';
        $totalRow[count($headings) - 1] = $this->num($total);
        $rows[] = $totalRow;

        $titles = ['income_tax' => 'PAYE Schedule', 'pension' => 'Pension Schedule', 'nhf' => 'NHF Schedule'];

        return [
            'headings' => $headings,
            'rows' => $rows,
            'title' => $titles[$code] ?? ucfirst($code),
        ];
    }

    private function num(mixed $v): float
    {
        return $v === null ? 0.0 : round((float) $v, 2);
    }

    // ---------------------------------------------------------------------
    //  Report B: registers & summaries
    // ---------------------------------------------------------------------

    /**
     * Headcount / gross / deductions / net grouped by a payslip column.
     * Powers the Departmental Summary (department_name) and Banks Summary
     * (bank_name) reports.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>, label: string}
     */
    public function groupedSummary(PayrollRun $run, string $column, string $label): array
    {
        $groups = $run->payslips()
            ->selectRaw("COALESCE(NULLIF({$column}, ''), '(none)') as grp")
            ->selectRaw('COUNT(*) c, SUM(gross) g, SUM(total_deductions) d, SUM(net_pay) n')
            ->groupBy('grp')->orderBy('grp')->get();

        $rows = [];
        $sn = 0;
        $tc = 0;
        $tg = $td = $tn = 0.0;
        foreach ($groups as $r) {
            $rows[] = [++$sn, $r->grp, (int) $r->c, $this->num($r->g), $this->num($r->d), $this->num($r->n)];
            $tc += (int) $r->c;
            $tg += (float) $r->g;
            $td += (float) $r->d;
            $tn += (float) $r->n;
        }
        $rows[] = ['', 'TOTAL', $tc, $this->num($tg), $this->num($td), $this->num($tn)];

        return [
            'headings' => ['S/N', $label, 'No. of Staff', 'Gross Pay', 'Deductions', 'Net Pay'],
            'rows' => $rows,
            'label' => $label,
        ];
    }

    /**
     * Double-entry payroll journal: salary heads debited (gross, consolidated
     * salary split by structure) against deduction liabilities and net pay
     * credited. Debit and credit totals both equal gross.
     *
     * @return array{debits: array<int,array{0:string,1:float}>, credits: array<int,array{0:string,1:float}>, total: float}
     */
    public function payrollJournal(PayrollRun $run): array
    {
        $lineAgg = fn () => DB::table('payslip_lines')
            ->join('payslips', 'payslips.id', '=', 'payslip_lines.payslip_id')
            ->where('payslips.payroll_run_id', $run->id);

        $debits = [];
        // Consolidated salary split by structure.
        $byStructure = $lineAgg()->where('payslip_lines.code', 'consolidated_salary')
            ->selectRaw('payslips.salary_structure s, SUM(payslip_lines.amount) t')
            ->groupBy('s')->orderBy('s')->get();
        foreach ($byStructure as $r) {
            $debits[] = [strtoupper($r->s ?: 'UNSPECIFIED').' SALARY', $this->num($r->t)];
        }
        // Other earnings, each as its own head.
        $otherEarnings = $lineAgg()->where('payslip_lines.type', PayComponent::TYPE_EARNING)
            ->where('payslip_lines.code', '!=', 'consolidated_salary')
            ->selectRaw('payslip_lines.name n, SUM(payslip_lines.amount) t')
            ->groupBy('n')->havingRaw('SUM(payslip_lines.amount) <> 0')->get();
        foreach ($otherEarnings as $r) {
            $debits[] = [strtoupper($r->n), $this->num($r->t)];
        }

        // Credits: every deduction/statutory head, then net payable.
        $credits = [];
        $deductions = $lineAgg()->where('payslip_lines.type', '!=', PayComponent::TYPE_EARNING)
            ->selectRaw('payslip_lines.name n, SUM(payslip_lines.amount) t')
            ->groupBy('n')->havingRaw('SUM(payslip_lines.amount) <> 0')->get();
        foreach ($deductions as $r) {
            $credits[] = [strtoupper($r->n), $this->num($r->t)];
        }
        $credits[] = ['NET PAYABLE', $this->num($run->total_net)];

        return [
            'debits' => $debits,
            'credits' => $credits,
            'total' => $this->num($run->total_gross),
        ];
    }

    /**
     * The wide payroll register split by department, each department carrying
     * its own additions/deductions totals. Used by the Departmental Payroll
     * Listing.
     *
     * @return array<int,array{department: string, register: array}>
     */
    public function departmentalListing(PayrollRun $run): array
    {
        $departments = $run->payslips()
            ->selectRaw("COALESCE(NULLIF(department_name, ''), '(none)') as dept")
            ->distinct()->orderBy('dept')->pluck('dept');

        $out = [];
        foreach ($departments as $dept) {
            $payslips = $run->payslips()
                ->when($dept === '(none)',
                    fn ($q) => $q->where(fn ($w) => $w->whereNull('department_name')->orWhere('department_name', '')),
                    fn ($q) => $q->where('department_name', $dept))
                ->with('lines')->orderBy('full_name')->get();

            $out[] = ['department' => $dept, 'register' => $this->wideRegister($payslips)];
        }

        return $out;
    }

    /**
     * Pivot a collection of payslips into the wide earnings/deductions grid
     * with column totals.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>, totals: array<int,mixed>}
     */
    private function wideRegister(Collection $payslips): array
    {
        $order = PayComponent::pluck('display_order', 'code');
        $earn = [];
        $deduct = [];
        foreach ($payslips as $slip) {
            foreach ($slip->lines as $line) {
                if ($line->type === PayComponent::TYPE_EARNING) {
                    $earn[$line->code] = $line->name;
                } else {
                    $deduct[$line->code] = $line->name;
                }
            }
        }
        $sortByOrder = fn (array $map) => collect($map)->sortBy(fn ($n, $c) => $order[$c] ?? 9999)->all();
        $earn = $sortByOrder($earn);
        $deduct = $sortByOrder($deduct);

        $headings = array_merge(
            ['S/N', 'Name', 'Grade'],
            array_values($earn),
            ['GROSS'],
            array_values($deduct),
            ['DEDUCTIONS', 'NET PAY'],
        );

        $rows = [];
        $sn = 0;
        $colTotals = [];
        foreach ($payslips as $slip) {
            $amounts = $slip->lines->keyBy('code')->map(fn ($l) => (float) $l->amount);
            $row = [++$sn, $slip->full_name, $slip->grade_level];
            $push = function ($key, $val) use (&$row, &$colTotals) {
                $row[] = $this->num($val);
                $colTotals[$key] = ($colTotals[$key] ?? 0) + (float) $val;
            };
            foreach (array_keys($earn) as $code) {
                $push('e_'.$code, $amounts[$code] ?? 0);
            }
            $push('gross', $slip->gross);
            foreach (array_keys($deduct) as $code) {
                $push('d_'.$code, $amounts[$code] ?? 0);
            }
            $push('ded', $slip->total_deductions);
            $push('net', $slip->net_pay);
            $rows[] = $row;
        }

        $totals = ['', 'TOTAL', ''];
        foreach (array_keys($earn) as $code) {
            $totals[] = $this->num($colTotals['e_'.$code] ?? 0);
        }
        $totals[] = $this->num($colTotals['gross'] ?? 0);
        foreach (array_keys($deduct) as $code) {
            $totals[] = $this->num($colTotals['d_'.$code] ?? 0);
        }
        $totals[] = $this->num($colTotals['ded'] ?? 0);
        $totals[] = $this->num($colTotals['net'] ?? 0);

        return ['headings' => $headings, 'rows' => $rows, 'totals' => $totals];
    }

    // ---------------------------------------------------------------------
    //  Report C: third-party & statutory schedules
    // ---------------------------------------------------------------------

    /** Deduction components that actually appear (non-zero) in the run. @return array<string,string> code => name */
    public function deductionComponents(PayrollRun $run): array
    {
        return DB::table('payslip_lines')
            ->join('payslips', 'payslips.id', '=', 'payslip_lines.payslip_id')
            ->where('payslips.payroll_run_id', $run->id)
            ->where('payslip_lines.type', PayComponent::TYPE_DEDUCTION)
            ->selectRaw('payslip_lines.code, payslip_lines.name')
            ->groupBy('payslip_lines.code', 'payslip_lines.name')
            ->havingRaw('SUM(payslip_lines.amount) > 0')
            ->orderBy('payslip_lines.name')
            ->pluck('name', 'code')->all();
    }

    /**
     * Per-member schedule for one deduction component (coops, loans, fees,
     * union dues, …).
     *
     * @return array{title: string, headings: array<int,string>, rows: array<int,array<int,mixed>>, total: float}
     */
    public function deductionSchedule(PayrollRun $run, string $code): array
    {
        $payslips = $run->payslips()
            ->whereHas('lines', fn ($q) => $q->where('code', $code)->where('amount', '>', 0))
            ->with(['lines' => fn ($q) => $q->where('code', $code)])
            ->orderBy('file_number')->get();

        $name = PayComponent::where('code', $code)->value('name') ?? $code;

        $rows = [];
        $sn = 0;
        $total = 0.0;
        foreach ($payslips as $slip) {
            $amt = (float) ($slip->lines->first()?->amount ?? 0);
            $rows[] = [++$sn, $slip->file_number, $slip->employee_code, $slip->full_name, $this->num($amt)];
            $total += $amt;
        }
        $rows[] = ['', '', '', 'TOTAL', $this->num($total)];

        return [
            'title' => "{$name} Deductions Schedule",
            'headings' => ['S/N', 'ID No.', 'IPPIS No.', 'Name', 'Amount'],
            'rows' => $rows,
            'total' => $this->num($total),
        ];
    }

    /**
     * Pension deductions summarised per PFA, with employer contribution derived
     * at the configured employer rate on the same pensionable base.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>}
     */
    public function pfaSummary(PayrollRun $run): array
    {
        $employerRate = (float) config('payroll.pension.employer_rate', 0.10);

        $groups = DB::table('payslip_lines')
            ->join('payslips', 'payslips.id', '=', 'payslip_lines.payslip_id')
            ->where('payslips.payroll_run_id', $run->id)
            ->where('payslip_lines.code', 'pension')
            ->selectRaw("COALESCE(NULLIF(payslips.pension_house, ''), '(none)') as pfa")
            ->selectRaw('COUNT(*) c, SUM(payslip_lines.amount) emp, SUM(payslip_lines.base) base')
            ->groupBy('pfa')->orderBy('pfa')->get();

        $rows = [];
        $sn = 0;
        $tc = 0;
        $te = $ter = $tt = 0.0;
        foreach ($groups as $r) {
            $employee = (float) $r->emp;
            $employer = round((float) $r->base * $employerRate, 2);
            $total = $employee + $employer;
            $rows[] = [++$sn, $r->pfa, (int) $r->c, $this->num($employee), $this->num($employer), $this->num($total)];
            $tc += (int) $r->c;
            $te += $employee;
            $ter += $employer;
            $tt += $total;
        }
        $rows[] = ['', 'TOTAL', $tc, $this->num($te), $this->num($ter), $this->num($tt)];

        return [
            'headings' => ['S/N', 'Pension Administrator', 'No. of Staff', 'Employee', 'Employer', 'Total'],
            'rows' => $rows,
        ];
    }

    /** Distinct PFAs present in the run. @return array<int,string> */
    public function pensionAdministrators(PayrollRun $run): array
    {
        return $run->payslips()
            ->whereHas('lines', fn ($q) => $q->where('code', 'pension')->where('amount', '>', 0))
            ->whereNotNull('pension_house')->where('pension_house', '!=', '')
            ->distinct()->orderBy('pension_house')->pluck('pension_house')->all();
    }

    /**
     * Per-member remittance schedule for one PFA (employee + employer + total).
     *
     * @return array{title: string, headings: array<int,string>, rows: array<int,array<int,mixed>>}
     */
    public function pfaSchedule(PayrollRun $run, string $pfa): array
    {
        $employerRate = (float) config('payroll.pension.employer_rate', 0.10);

        $payslips = $run->payslips()
            ->where('pension_house', $pfa)
            ->whereHas('lines', fn ($q) => $q->where('code', 'pension')->where('amount', '>', 0))
            ->with(['lines' => fn ($q) => $q->where('code', 'pension')])
            ->orderBy('full_name')->get();

        $rows = [];
        $sn = 0;
        $te = $ter = $tt = 0.0;
        foreach ($payslips as $slip) {
            $line = $slip->lines->first();
            $employee = (float) ($line?->amount ?? 0);
            $employer = round((float) ($line?->base ?? 0) * $employerRate, 2);
            $total = $employee + $employer;
            $rows[] = [++$sn, $slip->full_name, $slip->pen_number, $this->num($employee), $this->num($employer), $this->num($total)];
            $te += $employee;
            $ter += $employer;
            $tt += $total;
        }
        $rows[] = ['', 'TOTAL', '', $this->num($te), $this->num($ter), $this->num($tt)];

        return [
            'title' => "{$pfa} Schedule",
            'headings' => ['S/N', 'Name', 'RSA PIN', 'Employee', 'Employer', 'Total'],
            'rows' => $rows,
        ];
    }

    /**
     * Payment vouchers for every third-party deduction with a non-zero total.
     * Payee defaults to the component name.
     *
     * @return array<int,array{payee: string, particular: string, amount: float, words: string}>
     */
    public function paymentVouchers(PayrollRun $run): array
    {
        $vouchers = [];
        foreach ($this->deductionComponents($run) as $code => $name) {
            $total = (float) DB::table('payslip_lines')
                ->join('payslips', 'payslips.id', '=', 'payslip_lines.payslip_id')
                ->where('payslips.payroll_run_id', $run->id)
                ->where('payslip_lines.code', $code)
                ->sum('payslip_lines.amount');

            if ($total <= 0) {
                continue;
            }
            $vouchers[] = [
                'payee' => $name,
                'particular' => "Being payment to the above named for {$name} in the month of {$this->periodLabel($run)} vide attached details.",
                'amount' => $this->num($total),
                'words' => \App\Support\AmountInWords::naira($total),
            ];
        }

        return $vouchers;
    }

    // ---------------------------------------------------------------------
    //  Report D: cumulative / yearly
    // ---------------------------------------------------------------------

    /**
     * Month-by-month personnel expenditure for a calendar year.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>}
     */
    public function yearlySummary(int $year): array
    {
        $runs = PayrollRun::where('period', 'like', "{$year}-%")
            ->orderBy('period')->get();

        $rows = [];
        $sn = 0;
        $tg = $td = $tn = $tp = 0.0;
        $tc = 0;
        foreach ($runs as $run) {
            $pension = (float) DB::table('payslip_lines')
                ->join('payslips', 'payslips.id', '=', 'payslip_lines.payslip_id')
                ->where('payslips.payroll_run_id', $run->id)
                ->where('payslip_lines.code', 'pension')
                ->sum('payslip_lines.amount');

            $rows[] = [
                ++$sn,
                $this->periodLabel($run),
                (int) $run->employee_count,
                $this->num($run->total_gross),
                $this->num($run->total_deductions),
                $this->num($run->total_net),
                $this->num($pension),
            ];
            $tc += (int) $run->employee_count;
            $tg += (float) $run->total_gross;
            $td += (float) $run->total_deductions;
            $tn += (float) $run->total_net;
            $tp += $pension;
        }
        $rows[] = ['', 'TOTAL', $tc, $this->num($tg), $this->num($td), $this->num($tn), $this->num($tp)];

        return [
            'headings' => ['S/N', 'Month', 'Staff', 'Gross Salary', 'Deductions', 'Net Pay', 'Employee Pension'],
            'rows' => $rows,
        ];
    }

    /**
     * A single employee's pay record across a year: one row per month with the
     * headline figures.
     *
     * @return array{headings: array<int,string>, rows: array<int,array<int,mixed>>}
     */
    public function payRecordCard(Employee $employee, int $year): array
    {
        $payslips = \App\Models\Payslip::where('employee_id', $employee->id)
            ->whereHas('run', fn ($q) => $q->where('period', 'like', "{$year}-%"))
            ->with(['run:id,period', 'lines'])
            ->get()
            ->sortBy(fn ($p) => $p->run?->period)
            ->values();

        $rows = [];
        $tg = $tt = $tpen = $tnhf = $tn = 0.0;
        foreach ($payslips as $slip) {
            $pension = (float) ($slip->lines->firstWhere('code', 'pension')?->amount ?? 0);
            $nhf = (float) ($slip->lines->firstWhere('code', 'nhf')?->amount ?? 0);
            $rows[] = [
                $this->monthName($slip->run?->period),
                $slip->grade_level,
                $this->num($slip->gross),
                $this->num($slip->tax),
                $this->num($pension),
                $this->num($nhf),
                $this->num($slip->total_deductions),
                $this->num($slip->net_pay),
            ];
            $tg += (float) $slip->gross;
            $tt += (float) $slip->tax;
            $tpen += $pension;
            $tnhf += $nhf;
            $tn += (float) $slip->net_pay;
        }
        $rows[] = ['TOTAL', '', $this->num($tg), $this->num($tt), $this->num($tpen), $this->num($tnhf), '', $this->num($tn)];

        return [
            'headings' => ['Month', 'Grade', 'Gross Pay', 'PAYE', 'Pension', 'NHF', 'Deductions', 'Net Pay'],
            'rows' => $rows,
        ];
    }

    private function periodLabel(PayrollRun $run): string
    {
        return $run->period_start
            ? $run->period_start->format('F Y')
            : $run->period;
    }

    private function monthName(?string $period): string
    {
        if (! $period) {
            return '';
        }

        return \Carbon\Carbon::createFromFormat('Y-m', $period)->format('F Y');
    }
}
