/* SMS across the platform: what is left on the TumaSend account, how many SMS each business has used, SMS to business
   owners (payment reminders, notices) and what was sent. The admin's SMS don't use a business's own credits. */
import { Link, router, useForm } from '@inertiajs/react';
import { useState, type FormEvent } from 'react';
import { BarChart3, History, MessageSquareText, RefreshCw, Send, Wallet } from 'lucide-react';
import PlatformLayout from '../../layouts/PlatformLayout';
import { Badge, Button, Card, CardHeader, Choice, EmptyState, Field, PageHeader, Select, Stat, Textarea, cx, type Tone } from '../../components/ui';
import type { BillingStatus } from '../../types';

type Account = { state: 'ok'; credits: number; checked: string } | { state: 'off'; driver: string } | { state: 'sandbox' | 'no_key' | 'error' };
type Props = {
    account: Account;
    usage: { id: number; name: string; credits: number; thisMonth: number; failed: number; total: number }[];
    businesses: { id: number; name: string; owner: string | null; phone: string | null; status: BillingStatus }[];
    statuses: Record<string, string>;
    reasons: Record<string, string>;
    templates: Record<string, string>;
    placeholders: string[];
    sent: { id: number; when: string; business: string | null; to: string; reason: string; message: string; status: string; error: string | null; by: string | null }[];
    sentThisMonth: number;
    initial: { business_id: number | null };
};

const TONE: Record<string, Tone> = { sent: 'green', queued: 'amber', failed: 'rose', skipped: 'gray' };
const parts = (text: string) => (text.length <= 160 ? 1 : Math.ceil(text.length / 153));

function AccountCard({ account }: { account: Account }) {
    const note: Record<string, string> = {
        off: 'SMS sending is switched off on this server (SMS_DRIVER is not tumasend), so nothing is really sent.',
        sandbox: 'You are using a TumaSend test key: texts are simulated and free, so there is no balance.',
        no_key: 'To see your balance here, ask TumaSend for a System API key and put it in the .env file as TUMASEND_SYSTEM_KEY. Sending works without it.',
        error: 'TumaSend did not give the balance. Check that TUMASEND_SYSTEM_KEY is right, then refresh.',
    };
    return (
        <Card>
            <CardHeader icon={Wallet} title="TumaSend balance" subtitle="SMS left on your account, for every business."
                action={account.state === 'ok' || account.state === 'error'
                    ? <Button variant="ghost" size="sm" icon={RefreshCw} onClick={() => router.get(route('platform.sms'), { refresh: 1 }, { preserveScroll: true, only: ['account'] })}>Refresh</Button>
                    : undefined} />
            {account.state === 'ok' ? (
                <div className="mt-3">
                    <p className={cx('text-4xl font-extrabold', account.credits < 100 ? 'text-rose-600' : 'text-ink')}>{account.credits.toLocaleString()}</p>
                    <p className="mt-1 text-xs text-muted">SMS left · checked at {account.checked}{account.credits < 100 ? ' · running low: top up on TumaSend' : ''}</p>
                </div>
            ) : <p className="mt-3 rounded-xl bg-amber-50 p-3 text-sm text-amber-900">{note[account.state]}</p>}
        </Card>
    );
}

function SendForm({ businesses, statuses, reasons, templates, placeholders, initial }: Pick<Props, 'businesses' | 'statuses' | 'reasons' | 'templates' | 'placeholders' | 'initial'>) {
    const form = useForm({
        audience: initial.business_id ? 'one' : 'status',
        business_id: initial.business_id ? String(initial.business_id) : '',
        status: 'overdue',
        reason: 'payment_reminder',
        message: templates.payment_reminder,
    });
    const err = form.errors as Record<string, string | undefined>;
    const count = form.data.audience === 'one' ? (form.data.business_id ? 1 : 0)
        : businesses.filter((b) => b.phone && (form.data.audience === 'all' || b.status === form.data.status)).length;
    const submit = (e: FormEvent) => {
        e.preventDefault();
        if (count > 1 && !window.confirm(`Send this SMS to ${count} business owners?`)) return;
        form.post(route('platform.sms.send'), { preserveScroll: true, onSuccess: () => form.setData('message', templates[form.data.reason] ?? '') });
    };

    return (
        <Card>
            <CardHeader icon={Send} title="Send an SMS to business owners" subtitle="Goes to each owner's phone. Paid from your TumaSend account, not their SMS." />
            <form onSubmit={submit} className="mt-4 space-y-4" noValidate>
                <Field label="Reason" htmlFor="sms-reason">
                    <Select id="sms-reason" value={form.data.reason} onChange={(e) => form.setData((d) => ({ ...d, reason: e.target.value, message: templates[e.target.value] ?? '' }))}>
                        {Object.entries(reasons).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
                    </Select>
                </Field>
                <fieldset>
                    <legend className="mb-1.5 text-sm font-semibold text-ink">Send to</legend>
                    <div className="grid gap-2 sm:grid-cols-3">
                        <Choice name="audience" value="one" checked={form.data.audience === 'one'} onChange={() => form.setData('audience', 'one')}>One business</Choice>
                        <Choice name="audience" value="status" checked={form.data.audience === 'status'} onChange={() => form.setData('audience', 'status')}>By billing status</Choice>
                        <Choice name="audience" value="all" checked={form.data.audience === 'all'} onChange={() => form.setData('audience', 'all')}>Every business</Choice>
                    </div>
                </fieldset>
                {form.data.audience === 'one' && (
                    <Field label="Business" htmlFor="sms-business" error={err.business_id}>
                        <Select id="sms-business" value={form.data.business_id} onChange={(e) => form.setData('business_id', e.target.value)}>
                            <option value="">Choose…</option>
                            {businesses.map((b) => <option key={b.id} value={String(b.id)} disabled={!b.phone}>{b.name}{b.owner ? ` · ${b.owner}` : ''}{b.phone ? ` · ${b.phone}` : ' · no phone'}</option>)}
                        </Select>
                    </Field>
                )}
                {form.data.audience === 'status' && (
                    <Field label="Businesses that are" htmlFor="sms-status" error={err.status}>
                        <Select id="sms-status" value={form.data.status} onChange={(e) => form.setData('status', e.target.value)}>
                            {Object.entries(statuses).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
                        </Select>
                    </Field>
                )}
                <Field label="Message" htmlFor="sms-text" error={err.message ?? err.audience}
                    hint={<>Filled in for each business: {placeholders.join(' ')}. About {parts(form.data.message)} SMS each.</>}>
                    <Textarea id="sms-text" rows={5} value={form.data.message} onChange={(e) => form.setData('message', e.target.value)} />
                </Field>
                <Button type="submit" icon={Send} disabled={form.processing || count === 0}>
                    {form.processing ? 'Sending…' : count === 0 ? 'Nobody to send to' : `Send to ${count} owner${count === 1 ? '' : 's'}`}
                </Button>
            </form>
        </Card>
    );
}

export default function Sms({ account, usage, businesses, statuses, reasons, templates, placeholders, sent, sentThisMonth, initial }: Props) {
    const [open, setOpen] = useState<number | null>(null);
    const usedThisMonth = usage.reduce((n, u) => n + u.thisMonth, 0);

    return (
        <PlatformLayout title="SMS">
            <PageHeader title="SMS" subtitle="Your TumaSend balance, what each business uses, and SMS to business owners." />
            <div className="grid gap-6 lg:grid-cols-[340px_minmax(0,1fr)]">
                <div className="space-y-6">
                    <AccountCard account={account} />
                    <div className="grid grid-cols-2 gap-3">
                        <Stat label="Businesses, this month" value={usedThisMonth} icon={MessageSquareText} />
                        <Stat label="Yours, this month" value={sentThisMonth} icon={Send} tone="violet" />
                    </div>
                </div>
                <SendForm businesses={businesses} statuses={statuses} reasons={reasons} templates={templates} placeholders={placeholders} initial={initial} />
            </div>

            <Card className="mt-6" pad={false}>
                <div className="p-4 sm:p-5"><CardHeader icon={BarChart3} title="SMS used by each business" subtitle="Reminders they sent to their customers. Most this month first." /></div>
                {usage.length ? (
                    <div className="overflow-x-auto">
                        <table className="w-full min-w-[520px] text-sm">
                            <thead className="border-y border-line bg-line-2/50 text-left text-xs text-muted">
                                <tr><th className="px-4 py-2 font-semibold sm:px-5">Business</th><th className="px-3 py-2 text-right font-semibold">SMS left</th><th className="px-3 py-2 text-right font-semibold">This month</th><th className="px-3 py-2 text-right font-semibold">Failed</th><th className="px-4 py-2 text-right font-semibold sm:px-5">All time</th></tr>
                            </thead>
                            <tbody className="divide-y divide-line">
                                {usage.map((u) => (
                                    <tr key={u.id}>
                                        <td className="px-4 py-2.5 sm:px-5"><Link href={route('platform.businesses.show', { business: u.id })} className="font-bold text-ink hover:text-brand">{u.name}</Link></td>
                                        <td className={cx('px-3 py-2.5 text-right font-bold', u.credits === 0 ? 'text-rose-600' : 'text-ink')}>{u.credits}</td>
                                        <td className="px-3 py-2.5 text-right text-ink">{u.thisMonth}</td>
                                        <td className={cx('px-3 py-2.5 text-right', u.failed ? 'font-bold text-rose-600' : 'text-muted')}>{u.failed}</td>
                                        <td className="px-4 py-2.5 text-right text-muted sm:px-5">{u.total}</td>
                                    </tr>
                                ))}
                            </tbody>
                        </table>
                    </div>
                ) : <div className="px-4 pb-4"><EmptyState icon={BarChart3}>No businesses yet.</EmptyState></div>}
            </Card>

            <Card className="mt-6">
                <CardHeader icon={History} title="SMS you sent" subtitle="The last 50." />
                {sent.length ? (
                    <ul className="mt-2 divide-y divide-line">
                        {sent.map((m) => (
                            <li key={m.id} className="py-2.5">
                                <button type="button" onClick={() => setOpen(open === m.id ? null : m.id)} className="flex w-full items-center gap-3 text-left">
                                    <div className="min-w-0 flex-1">
                                        <p className="truncate text-sm font-bold text-ink">{m.business ?? m.to} <span className="font-normal text-muted">· {m.reason} · {m.when}</span></p>
                                        <p className={cx('text-sm text-ink-2', open !== m.id && 'truncate')}>{m.message}</p>
                                    </div>
                                    <Badge tone={TONE[m.status] ?? 'gray'}>{m.status === 'skipped' ? 'not sent' : m.status}</Badge>
                                </button>
                                {open === m.id && <p className="mt-1 text-xs text-muted">To {m.to}{m.by ? ` · by ${m.by}` : ''}{m.error ? ` · ${m.error}` : ''}</p>}
                                {open !== m.id && m.error && m.status !== 'sent' && <p className="mt-0.5 truncate text-xs text-rose-700">{m.error}</p>}
                            </li>
                        ))}
                    </ul>
                ) : <EmptyState icon={History}>Nothing sent yet.</EmptyState>}
            </Card>
        </PlatformLayout>
    );
}
