/* Profit and loss for the owner: today, this week, this month, last month or chosen dates. Sales per day and best
   sellers as simple bars (no chart library: small and fast). "Save as PDF" uses the phone's print (Save as PDF);
   "Share on WhatsApp" sends a short summary; CSV downloads open in Excel or Google Sheets. */
import { Link, router, usePage } from '@inertiajs/react';
import { useState, type ReactNode } from 'react';
import { BarChart3, ChevronRight, Download, FileText, MessageCircle, Trophy } from 'lucide-react';
import ShopLayout from '../../layouts/ShopLayout';
import { Button, Card, CardHeader, EmptyState, Input, cx } from '../../components/ui';
import { useT } from '../../i18n';
import type { SharedProps } from '../../types';

type Fig = { value: number; label: string };
type Day = { date: string; label: string; short: string; weekday: string; total: number; totalLabel: string; shortLabel: string; today: boolean; future: boolean; inPeriod: boolean };

/** One line of the profit and loss: what it is, a few words on what it means, and the amount. */
function Row({ sign, label, hint, value, strong, children }: { sign?: '−' | '+'; label: ReactNode; hint?: ReactNode; value: string; strong?: boolean; children?: ReactNode }) {
    return (
        <div className={cx('flex items-start justify-between gap-3 py-2.5', strong && 'border-t border-line')}>
            <div className="min-w-0">
                <p className={cx('text-[15px]', strong ? 'font-bold text-ink' : 'text-ink-2')}>{sign && <span className="mr-1.5 inline-block w-3 text-muted">{sign}</span>}{label}</p>
                {hint && <p className={cx('text-xs text-muted', sign && 'pl-[18px]')}>{hint}</p>}
                {children}
            </div>
            <p className={cx('shrink-0 text-right', strong ? 'font-extrabold text-ink' : 'font-bold text-ink')}>{value}</p>
        </div>
    );
}

/** Sales per day as bars: always a whole week or month, today marked, days to come left empty. Tap a bar for its total. */
function DayChart({ days }: { days: Day[] }) {
    const past = days.filter((d) => !d.future);
    const [picked, setPicked] = useState<string | null>(null);
    const max = Math.max(1, ...days.map((d) => d.total));
    const week = days.length <= 7;
    const every = week ? 1 : Math.ceil(days.length / 8);
    const best = past.reduce<Day | null>((b, d) => (d.total > (b?.total ?? 0) ? d : b), null);
    const shown = days.find((d) => d.date === picked) ?? days.find((d) => d.today) ?? past[past.length - 1];

    return (
        <>
            <div className="mt-6 flex h-48 items-stretch gap-1 sm:gap-1.5" role="img" aria-label="Sales per day">
                {days.map((d, i) => {
                    const h = (d.total / max) * 100;
                    return (
                        <button key={d.date} type="button" disabled={d.future} onClick={() => setPicked(d.date)} title={`${d.label}: ${d.totalLabel}`}
                            className="group flex min-w-0 flex-1 flex-col items-center gap-1 disabled:cursor-default">
                            <div className="relative flex w-full flex-1 items-end justify-center">
                                {d.future ? <div className="h-full w-full max-w-11 rounded-md border border-dashed border-line" /> : (
                                    <div className={cx('relative w-full max-w-11 rounded-t-md transition-colors', d.date === shown?.date ? 'bg-brand' : d.inPeriod ? 'bg-brand/60 group-hover:bg-brand/80' : 'bg-brand/25 group-hover:bg-brand/40')}
                                        style={{ height: `${h}%`, minHeight: d.total ? 4 : 2 }}>
                                        {week && d.total > 0 && <span className="absolute -top-4 left-1/2 -translate-x-1/2 text-[10px] font-bold whitespace-nowrap text-ink-2">{d.shortLabel}</span>}
                                    </div>
                                )}
                            </div>
                            <span className={cx('h-4 text-[10px] leading-4', d.today ? 'font-extrabold text-brand' : 'font-semibold text-muted')}>{i % every === 0 || d.today ? (week ? d.weekday : d.short) : ''}</span>
                        </button>
                    );
                })}
            </div>
            <div className="mt-3 flex flex-wrap items-center justify-between gap-2 rounded-xl bg-line-2/60 px-3 py-2 text-sm">
                {shown && <p><span className="text-muted">{shown.today ? 'Today' : shown.label}:</span> <b className="text-ink">{shown.totalLabel}</b></p>}
                {best && <p><span className="text-muted">Best day:</span> <b className="text-ink">{best.label}, {best.totalLabel}</b></p>}
            </div>
        </>
    );
}
type Props = {
    period: { key: string; from: string; to: string; label: string; dates: string };
    periods: Record<string, string>;
    figures: { sales: Fig; salesCount: number; cogs: Fig; gross: Fig; stockLoss: Fig; suppliesUsed: Fig; balesBought: Fig; expenses: Fig; net: Fig; creditSales: Fig; repaid: Fig; cashIn: Fig; owedNow: Fig };
    expensesByCategory: { label: string; total: string; amount: number }[];
    daily: Day[];
    dayTotal: boolean;
    best: { name: string; qtyLabel: string; totalLabel: string; profitLabel: string; total: number }[];
    printInfo: { name: string; printed: string };
};

export default function Report({ period, periods, figures: f, expensesByCategory, daily, dayTotal, best, printInfo: business }: Props) {
    const t = useT();
    const loans = !!usePage<SharedProps>().props.business?.loansEnabled;
    const [from, setFrom] = useState(period.from);
    const [to, setTo] = useState(period.to);
    const go = (params: Record<string, string>) => router.get(route('reports'), params, { preserveScroll: true });
    const query = period.key === 'custom' ? { period: 'custom', from: period.from, to: period.to } : { period: period.key };
    const maxBest = Math.max(1, ...best.map((b) => b.total));
    const lost = f.net.value < 0;
    const when = period.key === 'custom' ? period.dates : t(period.label);

    const share = [
        `*${business.name}* · ${period.label} (${period.dates})`,
        `Sales: ${f.sales.label} (${f.salesCount})`,
        `Cost of goods: ${f.cogs.label}`,
        `Gross profit: ${f.gross.label}`,
        ...(f.stockLoss.value !== 0 ? [`${f.stockLoss.value > 0 ? 'Stock missing' : 'Extra stock found'}: ${f.stockLoss.label.replace('-', '')}`] : []),
        ...(f.balesBought.value > 0 ? [`Bales bought: ${f.balesBought.label}`] : []),
        ...(f.suppliesUsed.value > 0 ? [`Supplies used: ${f.suppliesUsed.label}`] : []),
        `Expenses: ${f.expenses.label}`,
        `*${lost ? 'Loss' : 'Net profit'}: ${f.net.label.replace('-', '')}*`,
        ...(loans ? [`Owed by customers: ${f.owedNow.label}`] : []),
    ].join('\n');

    return (
        <ShopLayout title="Profit and loss">
            <div className="print:hidden">
                <h1 className="mb-3 text-2xl font-extrabold tracking-tight text-ink">{t('Profit and loss')}</h1>
                <div className="no-scrollbar -mx-4 mb-3 flex gap-2 overflow-x-auto px-4">
                    {Object.entries(periods).filter(([k]) => k !== 'custom').map(([k, v]) => (
                        <button key={k} onClick={() => go({ period: k })} className={cx('shrink-0 rounded-full px-4 py-2 text-sm font-bold', period.key === k ? 'bg-ink text-white' : 'bg-white text-ink-2 ring-1 ring-line')}>{t(v)}</button>
                    ))}
                </div>
                {/* two dates side by side, "Go" underneath on a phone (beside them on a computer) */}
                <div className="mb-4 grid grid-cols-2 gap-2 sm:flex sm:items-center">
                    <Input type="date" value={from} max={to} onChange={(e) => setFrom(e.target.value)} aria-label="From" className="min-w-0 sm:flex-1" />
                    <Input type="date" value={to} min={from} onChange={(e) => setTo(e.target.value)} aria-label="To" className="min-w-0 sm:flex-1" />
                    <Button variant={period.key === 'custom' ? 'dark' : 'secondary'} className="col-span-2" onClick={() => go({ period: 'custom', from, to })}>Show these dates</Button>
                </div>
            </div>

            {/* printed (Save as PDF) from here down */}
            <div className="mb-3 hidden print:block">
                <p className="text-xl font-extrabold">{business.name}</p>
                <p className="text-sm">Profit and loss · {period.label} ({period.dates}) · printed {business.printed}</p>
            </div>
            <p className="mb-3 text-sm font-semibold text-muted print:hidden">{period.dates}</p>

            {/* in one sentence first, then line by line */}
            <div className={cx('mb-4 rounded-card p-4 ring-1', lost ? 'bg-rose-50 text-rose-950 ring-rose-200' : 'bg-emerald-50 text-emerald-950 ring-emerald-200')}>
                <p className="text-sm font-semibold opacity-80">{lost ? 'Loss' : 'Profit'} · {when}</p>
                <p className="text-3xl font-extrabold tracking-tight">{f.net.label.replace('-', '')}</p>
                <p className="mt-1 text-sm">
                    You sold <b>{f.sales.label}</b> ({f.salesCount} sale{f.salesCount === 1 ? '' : 's'}).{' '}
                    After paying for the goods{f.stockLoss.value > 0 ? ', the stock that went missing' : ''} and expenses, you {f.net.value === 0 ? 'broke even' : lost ? <>lost <b>{f.net.label.replace('-', '')}</b></> : <>made <b>{f.net.label}</b></>}.
                </p>
            </div>

            <Card className="mb-4">
                <div className="divide-y divide-line/60">
                    <Row label={`Money from sales (${f.salesCount})`} hint="Everything sold, including on credit" value={f.sales.label} />
                    <Row sign="−" label="What the goods cost you" hint={dayTotal ? 'What went out, from your stock counts' : 'What you paid for the items you sold'} value={f.cogs.label} />
                    <Row strong label="Profit on goods" hint="Sales minus what the goods cost" value={f.gross.label} />
                    {f.stockLoss.value !== 0 && (
                        <Row sign={f.stockLoss.value > 0 ? '−' : '+'} label={f.stockLoss.value > 0 ? 'Stock missing' : 'Extra stock found'}
                            hint={f.stockLoss.value > 0 ? 'Left without a sale, found by stock counts (at cost)' : 'More on the shelf than expected in stock counts (at cost)'} value={f.stockLoss.label.replace('-', '')}>
                            <Link href={route('stock-count.report', { from: period.from, to: period.to })} className="mt-0.5 inline-flex items-center pl-[18px] text-xs font-bold text-brand hover:underline print:hidden">See which products<ChevronRight className="size-3.5" aria-hidden /></Link>
                        </Row>
                    )}
                    {f.balesBought.value > 0 && <Row sign="−" label="Bales bought" value={f.balesBought.label} />}
                    {f.suppliesUsed.value > 0 && <Row sign="−" label="Supplies used" hint="Bottles opened" value={f.suppliesUsed.label} />}
                    <Row sign="−" label={t('Expenses')} hint="Rent, transport, wages and other costs you recorded" value={f.expenses.label} />
                </div>
                <div className={cx('mt-2 flex items-center justify-between rounded-xl px-3 py-2.5', lost ? 'bg-rose-50 text-rose-900' : 'bg-emerald-50 text-emerald-900')}>
                    <p className="text-base font-extrabold">{lost ? 'Your loss' : 'Your profit'}</p><p className="text-xl font-extrabold">{f.net.label.replace('-', '')}</p>
                </div>
                {loans && (
                    <>
                        <div className="mt-4 grid grid-cols-2 gap-2 text-sm">
                            <div className="rounded-xl bg-line-2/60 p-3"><p className="text-xs text-muted">Cash you received</p><p className="font-bold text-ink">{f.cashIn.label}</p><p className="text-xs text-muted">Paid sales, plus {f.repaid.label} paid back by customers</p></div>
                            <div className="rounded-xl bg-amber-50 p-3 text-amber-900"><p className="text-xs">Customers owe you</p><p className="font-bold">{f.owedNow.label}</p><p className="text-xs">In total today. {f.creditSales.label} was sold on credit in this period</p></div>
                        </div>
                        <p className="mt-3 text-xs text-muted">Credit sales count in your profit when you make them, but the cash only comes when the customer pays.</p>
                    </>
                )}
            </Card>

            <Card className="mb-4">
                <CardHeader icon={BarChart3} title="Sales per day" subtitle={daily.length <= 7 ? 'This week' : undefined} />
                {daily.every((d) => d.total === 0) ? <EmptyState icon={BarChart3}>No sales in these days.</EmptyState> : <DayChart days={daily} />}
            </Card>

            <div className="grid gap-4 md:grid-cols-2">
                <Card>
                    <CardHeader icon={Trophy} title="Best sellers" />
                    {best.length === 0 ? <p className="mt-3 text-sm text-muted">No product sales in this period.</p> : (
                        <ul className="mt-3 space-y-3">
                            {best.map((b) => (
                                <li key={b.name}>
                                    <div className="flex justify-between gap-2 text-sm"><span className="truncate font-semibold text-ink-2">{b.name} <span className="text-muted">× {b.qtyLabel}</span></span><span className="shrink-0 font-bold text-ink">{b.totalLabel}</span></div>
                                    <div className="mt-1 h-2 overflow-hidden rounded-full bg-line-2"><div className="h-full rounded-full bg-brand" style={{ width: `${(b.total / maxBest) * 100}%` }} /></div>
                                    <p className="mt-0.5 text-xs text-muted">profit {b.profitLabel}</p>
                                </li>
                            ))}
                        </ul>
                    )}
                </Card>
                <Card>
                    <CardHeader title={t('Expenses')} />
                    {expensesByCategory.length === 0 ? <p className="mt-3 text-sm text-muted">No expenses in this period.</p> : (
                        <ul className="mt-3 divide-y divide-line text-sm">
                            {expensesByCategory.map((e) => <li key={e.label} className="flex justify-between py-2"><span className="text-ink-2">{t(e.label)}</span><span className="font-bold text-ink">{e.total}</span></li>)}
                        </ul>
                    )}
                </Card>
            </div>

            <div className="mt-5 grid grid-cols-2 gap-2 print:hidden sm:flex sm:flex-wrap">
                <Button variant="secondary" icon={FileText} onClick={() => window.print()}>Save as PDF</Button>
                <Button variant="secondary" icon={MessageCircle} onClick={() => window.open(`https://wa.me/?text=${encodeURIComponent(share)}`, '_blank', 'noopener')}>Share on WhatsApp</Button>
                {(loans ? (['sales', 'expenses', 'debtors'] as const) : (['sales', 'expenses'] as const)).map((w) => (
                    <a key={w} href={route('reports.export', { what: w, ...query })} className="flex items-center justify-center gap-2 rounded-lg border border-line bg-white px-4 py-2.5 text-sm font-semibold text-ink-2 hover:bg-line-2">
                        <Download className="size-4" aria-hidden />{w === 'sales' ? 'Sales' : w === 'expenses' ? 'Expenses' : 'Debtors'} CSV
                    </a>
                ))}
            </div>
        </ShopLayout>
    );
}
