/* Your shift: open it with the cash in the till; close it by counting the cash. The app shows what it expects and
   the difference. Below: shifts others have open (owner), and past shifts. */
import { Link, router, useForm, usePage } from '@inertiajs/react';
import { useState, type FormEvent } from 'react';
import { ChevronRight, Clock, Lock, Play } from 'lucide-react';
import ShopLayout from '../../layouts/ShopLayout';
import { Button, Card, CardHeader, EmptyState, Field, Input, PageHeader, Pagination, Textarea, cx } from '../../components/ui';
import { useT } from '../../i18n';
import type { Paginated, SharedProps } from '../../types';

export type ShiftData = {
    id: number; by: string | null; closedBy: string | null; openedAt: string; closedAt: string | null; isOpen: boolean;
    openingCash: string; expectedCash: string | null; expectedInput: string | null; countedCash: string | null;
    difference: number | null; differenceLabel: string | null; note: string | null;
    summary: {
        salesTotal: string; salesCount: number; byMethod: { label: string; total: string; count: number }[];
        creditSales: string; loansGiven: string; repaid: string; repaidCash: string; expenses: string; expensesCash: string; cashSales: string;
    } | null;
};

export function Difference({ shift }: { shift: ShiftData }) {
    const t = useT();
    if (shift.difference === null) return null;
    const d = shift.difference;
    return (
        <span className={cx('rounded-lg px-2 py-0.5 text-sm font-extrabold', d === 0 ? 'bg-emerald-50 text-emerald-700' : d < 0 ? 'bg-rose-50 text-rose-700' : 'bg-amber-50 text-amber-800')}>
            {d === 0 ? t('Exactly right') : `${shift.differenceLabel} ${t(d < 0 ? 'short' : 'over')}`}
        </span>
    );
}

/** The cash sum: start + cash sales + cash paid back − cash spent = expected. */
export function CashSum({ shift }: { shift: ShiftData }) {
    const t = useT();
    const loans = !!usePage<SharedProps>().props.business?.loansEnabled;
    const s = shift.summary;
    if (!s) return null;
    const rows: [string, string, string?][] = [
        [t('Started with'), shift.openingCash],
        [t('Cash sales'), s.cashSales, '+'],
        ...(loans ? [[t('Cash paid back'), s.repaidCash, '+'] as [string, string, string]] : []),
        [t('Cash spent'), s.expensesCash, '−'],
    ];
    return (
        <dl className="space-y-1.5 text-[15px]">
            {rows.map(([label, value, sign]) => (
                <div key={label} className="flex justify-between gap-3"><dt className="text-ink-2">{sign && <span className="mr-1 text-muted">{sign}</span>}{label}</dt><dd className="font-bold text-ink">{value}</dd></div>
            ))}
            <div className="flex justify-between gap-3 border-t border-line pt-1.5"><dt className="font-bold text-ink">{t('Expected cash')}</dt><dd className="text-lg font-extrabold text-ink">{shift.expectedCash}</dd></div>
        </dl>
    );
}

export function Summary({ shift }: { shift: ShiftData }) {
    const t = useT();
    const loans = !!usePage<SharedProps>().props.business?.loansEnabled;
    const s = shift.summary;
    if (!s) return null;
    return (
        <div className="space-y-3 text-sm">
            <div className="flex items-baseline justify-between"><span className="text-ink-2">{t('Sales')} ({s.salesCount})</span><span className="text-xl font-extrabold text-ink">{s.salesTotal}</span></div>
            {s.byMethod.length > 0 && (
                <div>
                    <p className="mb-1 text-xs font-semibold text-muted">{t('Sales by payment')}</p>
                    <div className="flex flex-wrap gap-1.5">{s.byMethod.map((m) => <span key={m.label} className="rounded-lg bg-line-2 px-2 py-1 text-xs font-semibold text-ink-2">{t(m.label)}: {m.total}</span>)}</div>
                </div>
            )}
            <dl className="grid grid-cols-2 gap-2">
                {[...(loans ? [[t('Credit (pay later)'), s.creditSales], [t('Loans given'), s.loansGiven], [t('Paid'), s.repaid]] : []), [t('Expenses'), s.expenses]].map(([l, v]) => (
                    <div key={l} className="rounded-xl bg-line-2/60 p-2.5"><dt className="text-xs text-muted">{l}</dt><dd className="font-bold text-ink">{v}</dd></div>
                ))}
            </dl>
        </div>
    );
}

function CloseForm({ shift }: { shift: ShiftData }) {
    const t = useT();
    const form = useForm({ counted_cash: '', note: '' });
    const err = form.errors as Record<string, string | undefined>;
    const submit = (e: FormEvent) => { e.preventDefault(); form.post(route('shifts.close', { shift: shift.id })); };
    return (
        <form onSubmit={submit} className="mt-4 space-y-3 border-t border-line pt-4">
            <Field label={t('Count the cash in the till')} htmlFor="counted" error={err.counted_minor}>
                <Input id="counted" inputMode="decimal" placeholder={shift.expectedInput ?? '0'} value={form.data.counted_cash} onChange={(e) => form.setData('counted_cash', e.target.value)} />
            </Field>
            <Textarea rows={2} placeholder={t('Note (optional)')} value={form.data.note} onChange={(e) => form.setData('note', e.target.value)} />
            <Button type="submit" size="lg" variant="dark" icon={Lock} className="w-full" disabled={form.processing || !form.data.counted_cash}>{t('Close shift')}</Button>
        </form>
    );
}

export default function ShiftPage({ current, othersOpen, history }: { current: ShiftData | null; othersOpen: ShiftData[]; history: Paginated<ShiftData> }) {
    const t = useT();
    const { errors } = usePage<SharedProps>().props;
    const [opening, setOpening] = useState('');

    return (
        <ShopLayout title="My shift">
            <PageHeader title={t('My shift')} />

            {current ? (
                <Card>
                    <CardHeader icon={Clock} title={`${t('Shift open since')} ${current.openedAt}`} />
                    <div className="mt-4 grid gap-5 md:grid-cols-2">
                        <CashSum shift={current} />
                        <Summary shift={current} />
                    </div>
                    <CloseForm shift={current} />
                </Card>
            ) : (
                <form onSubmit={(e) => { e.preventDefault(); router.post(route('shifts.open'), { opening_cash: opening || '0' }); }} className="rounded-card border-2 border-brand/30 bg-white p-4 shadow-card">
                    <p className="text-base font-extrabold text-ink">{t('No shift open')}</p>
                    <Field label={t('Cash in the till now')} error={errors.opening_minor ?? errors.opening_cash} className="mt-3">
                        <div className="flex gap-2">
                            <Input inputMode="decimal" placeholder="0" value={opening} onChange={(e) => setOpening(e.target.value)} className="flex-1" />
                            <Button type="submit" icon={Play}>{t('Open shift')}</Button>
                        </div>
                    </Field>
                </form>
            )}

            {othersOpen.length > 0 && (
                <Card className="mt-4">
                    <CardHeader icon={Clock} title="Open now" />
                    <ul className="mt-2 divide-y divide-line">
                        {othersOpen.map((s) => (
                            <li key={s.id}>
                                <Link href={route('shifts.show', { shift: s.id })} className="flex items-center gap-3 py-2.5">
                                    <div className="flex-1"><p className="font-bold text-ink">{s.by}</p><p className="text-xs text-muted">since {s.openedAt} · expects {s.expectedCash}</p></div>
                                    <ChevronRight className="size-4 text-muted" aria-hidden />
                                </Link>
                            </li>
                        ))}
                    </ul>
                </Card>
            )}

            <h2 className="mt-6 mb-2 text-sm font-bold text-muted">{t('Past shifts')}</h2>
            {history.data.length === 0 ? <EmptyState icon={Clock}>No closed shifts yet.</EmptyState> : (
                <ul className="divide-y divide-line overflow-hidden rounded-card border border-line bg-white shadow-card">
                    {history.data.map((s) => (
                        <li key={s.id}>
                            <Link href={route('shifts.show', { shift: s.id })} className="flex items-center gap-3 px-4 py-3 hover:bg-line-2/50">
                                <div className="min-w-0 flex-1">
                                    <p className="truncate text-[15px] font-bold text-ink">{s.openedAt} → {s.closedAt?.split(', ')[1]}</p>
                                    <p className="truncate text-xs text-muted">{s.by} · counted {s.countedCash}</p>
                                </div>
                                <Difference shift={s} />
                            </Link>
                        </li>
                    ))}
                </ul>
            )}
            <Pagination page={history} />
        </ShopLayout>
    );
}
