/* One stock count in full, to go through with the staff: for every product, how the app arrived at what should be
   on the shelf (counted last time + added − sold), what was counted, and what is missing; the money; and who worked
   between the two counts. Printable. */
import { useState } from 'react';
import { AlertTriangle, CheckCircle2, PackageSearch, PackagePlus, Printer, Users } from 'lucide-react';
import ShopLayout from '../../layouts/ShopLayout';
import { Badge, Button, ButtonLink, Card, CardHeader, EmptyState, PageHeader, Toggle, cx } from '../../components/ui';

type Line = {
    name: string; start: string | null; added: string | null; sold: string | null; voided: string | null;
    expected: string; counted: string; out: string; state: 'missing' | 'extra' | 'ok'; value: string; cost: string;
};
type Person = { name: string; shifts: number; sales: number; voided: number; cashShort: string | null };
type Props = {
    count: {
        id: number; when: string; since: string; days: number; by: string | null; items: number;
        missingItems: number; missingValue: string; missingCost: string; extraItems: number; extraValue: string;
        valueOut: string; moneyRecorded: string | null; gap: string | null; gapValue: number | null; detailed: boolean;
    };
    lines: Line[]; people: Person[]; dayTotal: boolean;
};

export default function StockCountShow({ count, lines, people, dayTotal }: Props) {
    const [onlyDiff, setOnlyDiff] = useState(true);
    const shown = onlyDiff ? lines.filter((l) => l.state !== 'ok') : lines;
    // a day-total shop rings nothing up item by item: what went out is what was sold, not a loss
    const outWord = dayTotal ? 'Went out' : 'Missing';
    const showTill = count.detailed && !dayTotal;
    const diffLabel = (l: Line) => (l.state === 'ok' ? 'Matches' : l.state === 'missing' ? `${l.out} ${dayTotal ? 'out' : 'missing'}` : `${l.out} extra`);
    const tone = (l: Line) => (l.state === 'missing' ? (dayTotal ? 'amber' : 'rose') : l.state === 'extra' ? 'sky' : 'green') as 'rose' | 'amber' | 'sky' | 'green';

    return (
        <ShopLayout title="Stock count" wide>
            <PageHeader title={`Stock count · ${count.when}`} subtitle={`Covers ${count.since} to ${count.when} (${count.days} day${count.days === 1 ? '' : 's'})${count.by ? ` · counted by ${count.by}` : ''}`}
                back={{ href: route('stock-count'), label: 'Count stock' }}
                actions={<span className="flex gap-2 print:hidden">
                    <ButtonLink href={route('stock-count.report')} variant="secondary" icon={PackageSearch}>Missing stock</ButtonLink>
                    <Button variant="secondary" icon={Printer} onClick={() => window.print()}>Print</Button>
                </span>} />

            <div className="grid gap-3 sm:grid-cols-3">
                <div className={cx('rounded-card p-4 ring-1', count.missingItems ? (dayTotal ? 'bg-amber-50 text-amber-950 ring-amber-200' : '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">{outWord}: {count.missingItems} of {count.items} item{count.items === 1 ? '' : 's'}</p>
                    <p className="text-3xl font-extrabold tracking-tight">{count.missingValue}</p>
                    <p className="text-xs opacity-80">At your selling prices · {count.missingCost} at cost</p>
                </div>
                <div className="rounded-card bg-sky-50 p-4 text-sky-950 ring-1 ring-sky-200">
                    <p className="text-sm font-semibold opacity-80">More than expected: {count.extraItems} item{count.extraItems === 1 ? '' : 's'}</p>
                    <p className="text-3xl font-extrabold tracking-tight">{count.extraValue}</p>
                    <p className="text-xs opacity-80">Usually stock added without recording it</p>
                </div>
                {count.moneyRecorded ? (
                    <div className={cx('rounded-card p-4 ring-1', (count.gapValue ?? 0) > 0 ? 'bg-amber-50 text-amber-950 ring-amber-200' : 'bg-emerald-50 text-emerald-950 ring-emerald-200')}>
                        <p className="text-sm font-semibold opacity-80">Money recorded: {count.moneyRecorded}</p>
                        <p className="text-3xl font-extrabold tracking-tight">{(count.gapValue ?? 0) === 0 ? 'Matches' : count.gap}</p>
                        <p className="text-xs opacity-80">{(count.gapValue ?? 0) > 0 ? `Not accounted for: stock worth ${count.valueOut} went out` : (count.gapValue ?? 0) < 0 ? 'More money than the stock that went out: check prices' : 'The money matches the stock that went out'}</p>
                    </div>
                ) : (
                    <div className="rounded-card bg-white p-4 ring-1 ring-line">
                        <p className="text-sm font-semibold text-muted">How to read this</p>
                        <p className="mt-1 text-sm text-ink-2">{dayTotal
                            ? 'Expected is what the app had. What went out is what you sold; count every item to compare it with the money you recorded.'
                            : 'Expected = last count + stock added − sold at the till. Missing = expected − what was counted: it left without a sale.'}</p>
                    </div>
                )}
            </div>

            {!count.detailed && (
                <p className="mt-4 rounded-xl bg-line-2 p-3 text-sm text-ink-2">This count was saved before the app kept the full breakdown, so the last count, added and sold columns are empty. Counts from now on have them.</p>
            )}

            <Card className="mt-6" pad={false}>
                <div className="flex flex-wrap items-center justify-between gap-3 p-4 sm:p-5">
                    <CardHeader icon={AlertTriangle} title="Product by product" subtitle={showTill ? 'Cancelled: sold at the till and then cancelled, so it does not count as sold.' : undefined} />
                    <label className="flex items-center gap-2 text-sm font-semibold text-ink-2 print:hidden">
                        <Toggle checked={onlyDiff} onChange={setOnlyDiff} label="Only differences" />Only differences
                    </label>
                </div>
                {shown.length === 0 ? (
                    <div className="px-4 pb-5"><EmptyState icon={CheckCircle2}>Everything counted matches what the app expected.</EmptyState></div>
                ) : (
                    <>
                        {/* phones: one card per product */}
                        <ul className="divide-y divide-line border-t border-line md:hidden print:hidden">
                            {shown.map((l) => (
                                <li key={l.name} className="px-4 py-3">
                                    <div className="flex items-start justify-between gap-2">
                                        <p className="font-bold text-ink">{l.name}</p>
                                        <Badge tone={tone(l)}>{diffLabel(l)}</Badge>
                                    </div>
                                    <dl className="mt-1.5 grid grid-cols-3 gap-x-3 gap-y-1 text-xs">
                                        {showTill && <><Fig k="Last count" v={l.start} /><Fig k="Added" v={l.added ? `+${l.added}` : null} /><Fig k="Sold" v={l.sold ? `−${l.sold}` : null} /></>}
                                        <Fig k="Expected" v={l.expected} strong /><Fig k="Counted" v={l.counted} strong />
                                        {l.state !== 'ok' && <Fig k="Value" v={l.value} strong />}
                                    </dl>
                                    {l.voided && <p className="mt-1.5 text-xs font-semibold text-amber-800">{l.voided} sold and then cancelled</p>}
                                </li>
                            ))}
                        </ul>
                        {/* computers and print: a table */}
                        <div className="hidden overflow-x-auto md:block print:block">
                            <table className="w-full text-sm">
                                <thead className="border-y border-line bg-line-2/50 text-left text-xs text-muted">
                                    <tr>
                                        <th className="px-5 py-2 font-semibold">Product</th>
                                        {showTill && <><th className="px-3 py-2 text-right font-semibold">Last count</th><th className="px-3 py-2 text-right font-semibold">Added</th><th className="px-3 py-2 text-right font-semibold">Sold</th><th className="px-3 py-2 text-right font-semibold">Cancelled</th></>}
                                        <th className="px-3 py-2 text-right font-semibold">Expected</th>
                                        <th className="px-3 py-2 text-right font-semibold">Counted</th>
                                        <th className="px-3 py-2 text-right font-semibold">Difference</th>
                                        <th className="px-5 py-2 text-right font-semibold">Value</th>
                                    </tr>
                                </thead>
                                <tbody className="divide-y divide-line">
                                    {shown.map((l) => (
                                        <tr key={l.name} className={l.state === 'missing' && !dayTotal ? 'bg-rose-50/40' : undefined}>
                                            <td className="px-5 py-2.5 font-bold text-ink">{l.name}</td>
                                            {showTill && <>
                                                <td className="px-3 py-2.5 text-right text-ink-2">{l.start ?? '–'}</td>
                                                <td className="px-3 py-2.5 text-right text-ink-2">{l.added ? `+${l.added}` : '–'}</td>
                                                <td className="px-3 py-2.5 text-right text-ink-2">{l.sold ? `−${l.sold}` : '–'}</td>
                                                <td className={cx('px-3 py-2.5 text-right', l.voided ? 'font-bold text-amber-700' : 'text-muted')}>{l.voided ?? '–'}</td>
                                            </>}
                                            <td className="px-3 py-2.5 text-right font-semibold text-ink">{l.expected}</td>
                                            <td className="px-3 py-2.5 text-right font-semibold text-ink">{l.counted}</td>
                                            <td className="px-3 py-2.5 text-right"><Badge tone={tone(l)}>{diffLabel(l)}</Badge></td>
                                            <td className="px-5 py-2.5 text-right font-bold text-ink">{l.state === 'ok' ? '–' : l.value}</td>
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>
                    </>
                )}
            </Card>

            <Card className="mt-6">
                <CardHeader icon={Users} title="Who worked in this period" subtitle="From shifts and sales between the two counts." />
                {people.length ? (
                    <ul className="mt-2 divide-y divide-line">
                        {people.map((p) => (
                            <li key={p.name} className="flex flex-wrap items-center justify-between gap-2 py-2.5 text-sm">
                                <p className="font-bold text-ink">{p.name}</p>
                                <p className="flex flex-wrap gap-1.5">
                                    {p.shifts > 0 && <Badge>{p.shifts} shift{p.shifts === 1 ? '' : 's'}</Badge>}
                                    <Badge>{p.sales} sale{p.sales === 1 ? '' : 's'}</Badge>
                                    {p.voided > 0 && <Badge tone="amber">{p.voided} cancelled</Badge>}
                                    {p.cashShort && <Badge tone="rose">cash short {p.cashShort}</Badge>}
                                </p>
                            </li>
                        ))}
                    </ul>
                ) : <EmptyState icon={PackagePlus}>No shifts or sales in this period.</EmptyState>}
            </Card>
        </ShopLayout>
    );
}

function Fig({ k, v, strong }: { k: string; v: string | null; strong?: boolean }) {
    return (
        <div>
            <dt className="text-muted">{k}</dt>
            <dd className={cx(strong ? 'font-bold text-ink' : 'text-ink-2')}>{v ?? '–'}</dd>
        </div>
    );
}
