/* One customer: what they owe, everything they took and paid (newest first), and the actions: record a payment,
   record a loan, send an SMS reminder now (owner), WhatsApp them. Payments and loans also work offline. */
import { Link, router, useForm, usePage } from '@inertiajs/react';
import { useState, type FormEvent } from 'react';
import { ArrowDownLeft, ArrowUpRight, Ban, HandCoins, MessageCircle, MessageSquareText, Pencil, Phone, Plus, Send } from 'lucide-react';
import ShopLayout from '../../layouts/ShopLayout';
import { Badge, Button, Card, CardHeader, EmptyState, Field, Input, PageHeader, Textarea, Toggle, cx } from '../../components/ui';
import { Modal } from '../../components/overlays';
import { uuid } from '../../lib';
import { submitOrQueue } from '../../offline';
import { useT } from '../../i18n';
import type { SharedProps } from '../../types';

type Entry = {
    key: string; type: 'loan' | 'payment'; id: number; date: string; amount: string; by: string | null;
    items?: string | null; saleNumber?: number | null; saleId?: number | null; due?: string | null; balance?: string; status?: string; overdueDays?: number; canCancel?: boolean;
    method?: string; note?: string | null;
};
type Props = {
    customer: { id: number; name: string; phone: string; whatsapp: string | null; notes: string; smsReminders: boolean; balance: number; balanceLabel: string; balanceInput: string; nextDue: string | null; overdueDays: number };
    history: Entry[]; sms: { id: number; when: string; status: string; message: string }[]; smsEnabled: boolean; smsLeft: number; methods: Record<string, string>; today: string;
};

function PayForm({ c, methods, onDone }: { c: Props['customer']; methods: Record<string, string>; onDone: (queued: boolean) => void }) {
    const t = useT();
    const [data, setData] = useState({ amount: c.balanceInput, payment_method: 'cash', note: '' });
    const [errors, setErrors] = useState<Record<string, string>>({});
    const [busy, setBusy] = useState(false);
    const submit = (e: FormEvent) => {
        e.preventDefault();
        setBusy(true);
        submitOrQueue({
            url: route('customers.repay', { customer: c.id }), type: 'repayment', label: `${c.name} paid ${data.amount}`,
            data: { ...data, customer_id: c.id, client_uuid: uuid() },
            onSuccess: () => onDone(false), onQueued: () => onDone(true), onError: setErrors, onFinish: () => setBusy(false),
        });
    };
    return (
        <form onSubmit={submit} className="space-y-4" noValidate>
            <Field label={t('Amount')} htmlFor="p-amount" error={errors.amount_minor ?? errors.amount} hint={`${t('Owes')} ${c.balanceLabel}`}>
                <Input id="p-amount" inputMode="decimal" value={data.amount} onChange={(e) => setData({ ...data, amount: e.target.value })} autoFocus />
            </Field>
            <Field label={t('Paid with')}>
                <div className="grid grid-cols-2 gap-2">
                    {Object.entries(methods).map(([k, v]) => (
                        <button key={k} type="button" onClick={() => setData({ ...data, payment_method: k })} className={cx('rounded-xl border-2 px-3 py-2.5 text-sm font-bold', data.payment_method === k ? 'border-brand bg-brand/[0.06] text-brand' : 'border-line text-ink-2')}>{t(v)}</button>
                    ))}
                </div>
            </Field>
            <Input placeholder={t('Note (optional)')} value={data.note} onChange={(e) => setData({ ...data, note: e.target.value })} />
            <Button type="submit" size="lg" className="w-full" disabled={busy}>{busy ? t('Saving…') : t('Record payment')}</Button>
        </form>
    );
}

function LoanForm({ c, today, onDone }: { c: Props['customer']; today: string; onDone: (queued: boolean) => void }) {
    const t = useT();
    const [data, setData] = useState({ amount: '', items: '', loaned_on: today, due_on: '' });
    const [errors, setErrors] = useState<Record<string, string>>({});
    const [busy, setBusy] = useState(false);
    const submit = (e: FormEvent) => {
        e.preventDefault();
        setBusy(true);
        submitOrQueue({
            url: route('customers.lend', { customer: c.id }), type: 'loan', label: `${c.name} took ${data.amount}`,
            data: { ...data, customer_id: c.id, client_uuid: uuid() },
            onSuccess: () => onDone(false), onQueued: () => onDone(true), onError: setErrors, onFinish: () => setBusy(false),
        });
    };
    return (
        <form onSubmit={submit} className="space-y-4" noValidate>
            <p className="rounded-xl bg-line-2 p-3 text-xs text-ink-2">For goods taken without the till. At the till, choose “Credit” instead: it records the sale and the loan together.</p>
            <Field label={t('Amount')} htmlFor="l-amount" error={errors.amount_minor}><Input id="l-amount" inputMode="decimal" value={data.amount} onChange={(e) => setData({ ...data, amount: e.target.value })} autoFocus /></Field>
            <Field label={t('Items taken')} htmlFor="l-items" error={errors.items}><Input id="l-items" placeholder="e.g. 2 bags of sugar" value={data.items} onChange={(e) => setData({ ...data, items: e.target.value })} /></Field>
            <div className="grid grid-cols-2 gap-3">
                <Field label={t('Date')} error={errors.loaned_on}><Input type="date" max={today} value={data.loaned_on} onChange={(e) => setData({ ...data, loaned_on: e.target.value })} /></Field>
                <Field label={t('Due date')} error={errors.due_on}><Input type="date" value={data.due_on} onChange={(e) => setData({ ...data, due_on: e.target.value })} /></Field>
            </div>
            <Button type="submit" size="lg" className="w-full" disabled={busy}>{busy ? t('Saving…') : t('Record a loan')}</Button>
        </form>
    );
}

function EditForm({ c, owner, onDone }: { c: Props['customer']; owner: boolean; onDone: () => void }) {
    const t = useT();
    const form = useForm({ name: c.name, phone: c.phone, notes: c.notes, sms_reminders: c.smsReminders });
    const err = form.errors as Record<string, string | undefined>;
    const submit = (e: FormEvent) => { e.preventDefault(); form.put(route('customers.update', { customer: c.id }), { preserveScroll: true, onSuccess: onDone }); };
    return (
        <form onSubmit={submit} className="space-y-4" noValidate>
            <Field label={t('Name')} error={err.name}><Input value={form.data.name} onChange={(e) => form.setData('name', e.target.value)} /></Field>
            <Field label={t('Phone number')} error={err.phone_e164}><Input type="tel" inputMode="tel" value={form.data.phone} onChange={(e) => form.setData('phone', e.target.value)} /></Field>
            <Field label={t('Notes')}><Textarea rows={2} value={form.data.notes} onChange={(e) => form.setData('notes', e.target.value)} /></Field>
            {owner && (
                <div className="flex items-center justify-between gap-3 rounded-xl border border-line p-3">
                    <div><p className="text-sm font-bold text-ink">SMS reminders for this customer</p><p className="text-xs text-muted">Off: never texted, even when reminders are on.</p></div>
                    <Toggle checked={form.data.sms_reminders} onChange={(v) => form.setData('sms_reminders', v)} label="SMS reminders" />
                </div>
            )}
            <Button type="submit" size="lg" className="w-full" disabled={form.processing}>{t('Save')}</Button>
        </form>
    );
}

export default function CustomerPage({ customer: c, history, sms, smsLeft, methods, today }: Props) {
    const t = useT();
    const { auth } = usePage<SharedProps>().props;
    const owner = auth?.role === 'owner';
    const [modal, setModal] = useState<'pay' | 'loan' | 'edit' | null>(null);
    const [cancelling, setCancelling] = useState<Entry | null>(null);
    const [reason, setReason] = useState('');
    const done = () => setModal(null);

    return (
        <ShopLayout title={c.name}>
            <PageHeader title={c.name} subtitle={c.phone || 'No phone'} back={{ href: route('customers.index'), label: t('Customers') }}
                actions={<button onClick={() => setModal('edit')} className="grid size-10 place-items-center rounded-xl text-muted ring-1 ring-line hover:text-ink" aria-label="Edit"><Pencil className="size-4" /></button>} />

            <div className={cx('rounded-card p-4 shadow-card', c.balance ? 'bg-ink text-white' : 'bg-emerald-50 text-emerald-900')}>
                <p className="text-sm opacity-75">{c.balance ? t('Owes') : t('Paid up')}</p>
                <p className="text-3xl font-extrabold tracking-tight">{c.balanceLabel}</p>
                {c.overdueDays > 0 ? <p className="mt-1 text-sm font-bold text-rose-300">{c.overdueDays} {t('days late')}</p> : c.nextDue && <p className="mt-1 text-sm opacity-75">{t('Due date')}: {c.nextDue}</p>}
            </div>

            <div className="mt-3 grid grid-cols-2 gap-2">
                <Button size="lg" icon={ArrowDownLeft} onClick={() => setModal('pay')} disabled={!c.balance}>{t('Record payment')}</Button>
                <Button size="lg" variant="secondary" icon={Plus} onClick={() => setModal('loan')}>{t('Record a loan')}</Button>
            </div>
            <div className="mt-2 flex flex-wrap gap-2">
                {c.phone && <a href={`tel:${c.phone.replace(/\s/g, '')}`} className="flex items-center gap-1.5 rounded-xl bg-white px-3 py-2 text-sm font-semibold text-ink-2 ring-1 ring-line"><Phone className="size-4" aria-hidden />Call</a>}
                {c.whatsapp && <a href={c.whatsapp} target="_blank" rel="noopener" className="flex items-center gap-1.5 rounded-xl bg-white px-3 py-2 text-sm font-semibold text-emerald-700 ring-1 ring-line"><MessageCircle className="size-4" aria-hidden />WhatsApp</a>}
                {owner && c.balance > 0 && c.phone && (
                    // any time, due or not: it uses one of the prepaid SMS
                    <button onClick={() => router.post(route('customers.remind', { customer: c.id }), {}, { preserveScroll: true })} disabled={smsLeft === 0 || !c.smsReminders}
                        title={smsLeft === 0 ? 'No SMS left: buy more (More → SMS reminders)' : !c.smsReminders ? 'Reminders are off for this customer' : undefined}
                        className="flex items-center gap-1.5 rounded-xl bg-white px-3 py-2 text-sm font-semibold text-brand ring-1 ring-line disabled:opacity-40">
                        <Send className="size-4" aria-hidden />{t('Send reminder now')} <span className="font-normal text-muted">· {smsLeft} SMS left</span>
                    </button>
                )}
            </div>
            {c.notes && <p className="mt-3 text-sm text-muted">{c.notes}</p>}

            <h2 className="mt-6 mb-2 text-sm font-bold text-muted">{t('History')}</h2>
            {history.length === 0 ? <EmptyState icon={HandCoins}>Nothing yet.</EmptyState> : (
                <ul className="divide-y divide-line overflow-hidden rounded-card border border-line bg-white shadow-card">
                    {history.map((h) => (
                        <li key={h.key} className={cx('flex items-start gap-3 px-4 py-3', h.status === 'cancelled' && 'opacity-50')}>
                            <span className={cx('mt-0.5 grid size-8 shrink-0 place-items-center rounded-full', h.type === 'loan' ? 'bg-amber-50 text-amber-700' : 'bg-emerald-50 text-emerald-700')}>
                                {h.type === 'loan' ? <ArrowUpRight className="size-4" aria-hidden /> : <ArrowDownLeft className="size-4" aria-hidden />}
                            </span>
                            <div className="min-w-0 flex-1">
                                <p className="text-[15px] font-bold text-ink">{h.type === 'loan' ? t('Took') : t('Paid')} {h.amount}</p>
                                <p className="text-xs text-muted">
                                    {h.date}{h.by ? ` · ${h.by}` : ''}{h.method ? ` · ${t(h.method)}` : ''}
                                    {h.saleId && <> · <Link href={route('sales.show', { sale: h.saleId })} className="font-semibold text-brand">sale #{h.saleNumber}</Link></>}
                                </p>
                                {h.items && <p className="mt-0.5 text-sm text-ink-2">{h.items}</p>}
                                {h.note && <p className="mt-0.5 text-sm text-ink-2">{h.note}</p>}
                                {h.type === 'loan' && h.status !== 'cancelled' && (
                                    <div className="mt-1 flex flex-wrap items-center gap-1.5">
                                        {h.status === 'paid' ? <Badge tone="green">{t('Paid up')}</Badge> : <Badge tone={h.status === 'overdue' ? 'rose' : 'amber'}>{t('Owes')} {h.balance}{h.due ? ` · ${t('Due date')} ${h.due}` : ''}</Badge>}
                                        {h.canCancel && <button onClick={() => setCancelling(h)} className="text-xs font-semibold text-muted hover:text-rose-700">{t('Cancel')}</button>}
                                    </div>
                                )}
                                {h.status === 'cancelled' && <Badge>{t('Cancelled')}</Badge>}
                            </div>
                        </li>
                    ))}
                </ul>
            )}

            {owner && sms.length > 0 && (
                <Card className="mt-4">
                    <CardHeader icon={MessageSquareText} title="SMS sent" />
                    <ul className="mt-2 divide-y divide-line text-sm">
                        {sms.map((m) => <li key={m.id} className="py-2"><p className="text-ink-2">{m.message}</p><p className="text-xs text-muted">{m.when} · {m.status}</p></li>)}
                    </ul>
                </Card>
            )}

            <Modal open={modal === 'pay'} onClose={done} title={t('Record payment')} subtitle={c.name}>{modal === 'pay' && <PayForm c={c} methods={methods} onDone={done} />}</Modal>
            <Modal open={modal === 'loan'} onClose={done} title={t('Record a loan')} subtitle={c.name}>{modal === 'loan' && <LoanForm c={c} today={today} onDone={done} />}</Modal>
            <Modal open={modal === 'edit'} onClose={done} title={c.name}>{modal === 'edit' && <EditForm c={c} owner={owner} onDone={done} />}</Modal>
            <Modal open={!!cancelling} onClose={() => setCancelling(null)} title="Cancel this loan?" subtitle={cancelling ? `${cancelling.amount} · ${cancelling.date}` : ''}>
                <Field label="Why?"><Textarea rows={2} value={reason} onChange={(e) => setReason(e.target.value)} /></Field>
                <div className="mt-4 flex justify-end gap-2">
                    <Button variant="ghost" onClick={() => setCancelling(null)}>{t('Back')}</Button>
                    <Button variant="danger" icon={Ban} onClick={() => cancelling && router.post(route('loans.cancel', { loan: cancelling.id }), { reason }, { preserveScroll: true, onSuccess: () => setCancelling(null) })}>Cancel loan</Button>
                </div>
            </Modal>
        </ShopLayout>
    );
}
