import { router, useForm } from '@inertiajs/react';
import { AlertTriangle, CheckCircle2, Copy, Globe } from 'lucide-react';
import { useState } from 'react';
import { PageHeader } from '@/components/PageHeader';
import { SettingsNav } from '@/components/SettingsNav';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardBody, CardHeader } from '@/components/ui/card';
import { Input, Select } from '@/components/ui/input';
import { Field } from '@/components/ui/label';
import AppLayout from '@/layouts/AppLayout';
import { dateTime } from '@/lib/format';

type Dns = { type: string; host: string; value: string; verified: boolean; purpose: string };
type Props = {
    company: {
        name: string; sender_domain: string | null; sender_from_address: string | null; sender_from_name_format: string;
        sender_dns: Dns[] | null; sender_verified_at: string | null;
        proposal_domain: string | null; proposal_domain_status: string | null; proposal_domain_error: string | null; proposal_domain_verified_at: string | null;
    };
    appHost: string;
    mail: { provider: string; name: string; live: boolean; domains: boolean; webhook: boolean; webhook_url: string };
    fromFormats: Record<string, string>;
    canEdit: boolean;
};

function CopyValue({ value }: { value: string }) {
    const [done, setDone] = useState(false);
    return (
        <span className="flex min-w-0 items-center gap-1.5">
            <code className="min-w-0 flex-1 break-all rounded bg-stone-100 px-1.5 py-0.5 text-xs">{value}</code>
            <button type="button" className="shrink-0 rounded p-1 text-ink-muted hover:bg-stone-100" aria-label="Copy" onClick={() => { navigator.clipboard?.writeText(value); setDone(true); setTimeout(() => setDone(false), 1500); }}>
                {done ? <CheckCircle2 className="h-3.5 w-3.5 text-green-700" /> : <Copy className="h-3.5 w-3.5" />}
            </button>
        </span>
    );
}

/** Settings → Domains: the sending domain (DKIM / return path with the email provider) and the custom proposal domain. */
export default function Domains({ company, appHost, mail, fromFormats, canEdit }: Props) {
    const sender = useForm({ sender_from_address: company.sender_from_address ?? '', sender_from_name_format: company.sender_from_name_format });
    const proposal = useForm({ proposal_domain: company.proposal_domain ?? '' });
    const [busy, setBusy] = useState<string | null>(null);
    const post = (url: string) => { setBusy(url); router.post(url, {}, { preserveScroll: true, onFinish: () => setBusy(null) }); };
    const d = company.proposal_domain;
    const sub = d ? d.split('.')[0] : 'quotes';

    return (
        <AppLayout title="Domains">
            <PageHeader title="Domains" breadcrumbs={[{ label: 'Settings', href: '/settings/company' }, { label: 'Domains' }]}
                description={`How emails and client links look for ${company.name}.`} />
            <SettingsNav />
            <div className="grid max-w-4xl gap-6">
                <Card>
                    <CardHeader title="Sending domain" description="Emails come from your own address, signed with DKIM so they land in the inbox." actions={
                        company.sender_verified_at ? <Badge className="bg-green-100 text-green-800">Verified</Badge> : company.sender_domain ? <Badge className="bg-amber-100 text-amber-900">Not verified</Badge> : null} />
                    <CardBody className="space-y-4">
                        {mail.live ? (
                            <p className="flex gap-2 rounded-md border border-green-200 bg-green-50 px-3 py-2 text-sm text-green-900" data-testid="mail-provider"><CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0" />
                                Emails are sent through {mail.name}.</p>
                        ) : (
                            <p className="flex gap-2 rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-900" data-testid="mail-provider"><AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" />
                                No email provider is connected yet (add SMTP2GO_API_KEY to the server's .env), so emails are written to the server log instead of being sent.</p>
                        )}
                        <form className="grid gap-4 sm:grid-cols-2" onSubmit={(e) => { e.preventDefault(); sender.put('/settings/domains/sender', { preserveScroll: true }); }}>
                            <fieldset disabled={!canEdit} className="contents">
                                <Field label="From address" htmlFor="from" error={sender.errors.sender_from_address} hint="e.g. quotes@spindesign.com.au">
                                    <Input id="from" type="email" value={sender.data.sender_from_address} onChange={(e) => sender.setData('sender_from_address', e.target.value)} />
                                </Field>
                                <Field label="From name" htmlFor="from_name" error={sender.errors.sender_from_name_format}>
                                    <Select id="from_name" value={sender.data.sender_from_name_format} onChange={(e) => sender.setData('sender_from_name_format', e.target.value)}>
                                        {Object.entries(fromFormats).map(([k, v]) => <option key={k} value={k}>{k === 'first_at_company' ? `Owner's first name at company (${v})` : k === 'owner' ? `Owner's full name (${v})` : `Company name (${v})`}</option>)}
                                    </Select>
                                </Field>
                                {canEdit && <div className="sm:col-span-2 flex justify-end"><Button type="submit" disabled={sender.processing} data-testid="save-sender">Save sender</Button></div>}
                            </fieldset>
                        </form>

                        {company.sender_dns ? (
                            <div className="space-y-3">
                                <p className="text-sm">Add these records at your DNS host for <b>{company.sender_domain}</b>, then press Verify.</p>
                                <div className="overflow-x-auto">
                                    <table className="w-full text-sm">
                                        <thead><tr className="text-left text-xs text-ink-muted"><th className="pb-1.5 pr-3 font-medium">Record</th><th className="pb-1.5 pr-3 font-medium">Type</th><th className="pb-1.5 pr-3 font-medium">Host / name</th><th className="pb-1.5 pr-3 font-medium">Value</th><th className="pb-1.5 font-medium">Status</th></tr></thead>
                                        <tbody>
                                            {company.sender_dns.map((r) => (
                                                <tr key={r.host + r.purpose} className="border-t border-line align-top">
                                                    <td className="py-2 pr-3 text-xs">{r.purpose}</td>
                                                    <td className="py-2 pr-3 font-medium">{r.type}</td>
                                                    <td className="py-2 pr-3"><CopyValue value={r.host} /></td>
                                                    <td className="max-w-md py-2 pr-3"><CopyValue value={r.value} /></td>
                                                    <td className="py-2">{r.verified ? <Badge className="bg-green-100 text-green-800">OK</Badge> : <Badge className="bg-stone-100 text-stone-600">Pending</Badge>}</td>
                                                </tr>
                                            ))}
                                        </tbody>
                                    </table>
                                </div>
                                {canEdit && <Button type="button" variant="secondary" onClick={() => post('/settings/domains/sender/verify')} disabled={!!busy} data-testid="verify-sender">{busy === '/settings/domains/sender/verify' ? 'Checking…' : 'Verify'}</Button>}
                            </div>
                        ) : company.sender_domain && !mail.domains ? (
                            <p className="text-sm text-ink-muted">Once the email provider is connected, save the sender again to check the DKIM and return-path records for {company.sender_domain}.</p>
                        ) : null}

                        <details className="text-sm">
                            <summary className="cursor-pointer font-medium">Open and delivery tracking ({mail.provider === 'postmark' ? 'Postmark' : 'SMTP2GO'} webhook)</summary>
                            <div className="mt-2 space-y-1 text-ink-muted">
                                {mail.provider === 'postmark'
                                    ? <p>In Postmark → your server → Webhooks, add a webhook for Delivery, Bounce, Open and Click with this URL and the basic-auth user name and password from EMAIL_WEBHOOK_USER / EMAIL_WEBHOOK_PASSWORD:</p>
                                    : <p>In SMTP2GO → Settings → Tracking, switch on open and click tracking. Then in Settings → Webhooks, add a webhook with this URL, the events Delivered, Open, Click, Bounce, Reject and Spam, output JSON, the custom email header <code>X-SGQ-Email-Id</code>, and a Basic authorization header with the user name and password from EMAIL_WEBHOOK_USER / EMAIL_WEBHOOK_PASSWORD:</p>}
                                <CopyValue value={mail.webhook_url} />
                                <p>{mail.webhook ? 'Webhook credentials are set on the server.' : 'Webhook credentials are not set on the server yet.'}</p>
                            </div>
                        </details>
                    </CardBody>
                </Card>

                <Card>
                    <CardHeader title="Proposal domain" description={`Client links use ${d && company.proposal_domain_verified_at ? d : appHost} now. A domain of your own (like quotes.yourcompany.com.au) looks more trustworthy.`} actions={
                        company.proposal_domain_verified_at ? <Badge className="bg-green-100 text-green-800">Live</Badge> : d ? <Badge className="bg-amber-100 text-amber-900">Setting up</Badge> : null} />
                    <CardBody className="space-y-5">
                        <form className="flex flex-wrap items-end gap-3" onSubmit={(e) => { e.preventDefault(); proposal.put('/settings/domains/proposal', { preserveScroll: true }); }}>
                            <Field label="Domain" htmlFor="proposal_domain" error={proposal.errors.proposal_domain} className="min-w-64 flex-1">
                                <Input id="proposal_domain" placeholder="quotes.yourcompany.com.au" value={proposal.data.proposal_domain} onChange={(e) => proposal.setData('proposal_domain', e.target.value.trim().toLowerCase())} disabled={!canEdit} />
                            </Field>
                            {canEdit && <Button type="submit" variant="secondary" disabled={proposal.processing} data-testid="save-proposal-domain">Save</Button>}
                        </form>

                        {d && (
                            <ol className="space-y-4 text-sm">
                                <li className="flex gap-3">
                                    <Step n={1} done={company.proposal_domain_status === 'dns_ok' || company.proposal_domain_status === 'ssl_ok'} />
                                    <div className="min-w-0 flex-1">
                                        <div className="font-medium">Add a CNAME record at your DNS host</div>
                                        <div className="mt-1.5 grid max-w-xl grid-cols-[5rem_1fr] gap-x-3 gap-y-1">
                                            <span className="text-ink-muted">Type</span><code>CNAME</code>
                                            <span className="text-ink-muted">Name</span><CopyValue value={sub} />
                                            <span className="text-ink-muted">Points to</span><CopyValue value={appHost} />
                                        </div>
                                    </div>
                                </li>
                                <li className="flex gap-3">
                                    <Step n={2} done={company.proposal_domain_status === 'ssl_ok'} />
                                    <div className="min-w-0 flex-1">
                                        <div className="font-medium">Add the domain in cPanel</div>
                                        <p className="mt-1 text-ink-muted">cPanel → <b>Domains</b> → <b>Create a new domain</b>: enter <b>{d}</b>, untick “Share document root” and set the document root to the same folder as {appHost}. (This lets the server answer for {d}.)</p>
                                    </div>
                                </li>
                                <li className="flex gap-3">
                                    <Step n={3} done={company.proposal_domain_status === 'ssl_ok'} />
                                    <div className="min-w-0 flex-1">
                                        <div className="font-medium">Get the SSL certificate</div>
                                        <p className="mt-1 text-ink-muted">cPanel → <b>SSL/TLS Status</b> → tick {d} → <b>Run AutoSSL</b>. It usually takes a few minutes once the CNAME is live.</p>
                                    </div>
                                </li>
                                <li className="flex gap-3">
                                    <Step n={4} done={!!company.proposal_domain_verified_at} />
                                    <div className="min-w-0 flex-1">
                                        <div className="font-medium">Verify</div>
                                        <p className="mt-1 text-ink-muted">Checks the DNS record and that {d} serves this app over HTTPS. Only client pages are available on this domain.</p>
                                        {company.proposal_domain_error && <p className="mt-1.5 rounded-md bg-amber-50 px-3 py-2 text-amber-900" data-testid="proposal-domain-error">{company.proposal_domain_error}</p>}
                                        {company.proposal_domain_verified_at && <p className="mt-1.5 text-green-800">Verified {dateTime(company.proposal_domain_verified_at)}. New client links use {d}.</p>}
                                        {canEdit && <Button type="button" className="mt-2" onClick={() => post('/settings/domains/proposal/verify')} disabled={!!busy} data-testid="verify-proposal-domain">
                                            <Globe className="h-4 w-4" /> {busy === '/settings/domains/proposal/verify' ? 'Checking…' : 'Verify domain'}</Button>}
                                    </div>
                                </li>
                            </ol>
                        )}
                    </CardBody>
                </Card>
            </div>
        </AppLayout>
    );
}

function Step({ n, done }: { n: number; done: boolean }) {
    return <span className={`flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-xs font-semibold ${done ? 'bg-green-100 text-green-800' : 'bg-accent-soft text-link'}`}>{done ? <CheckCircle2 className="h-4 w-4" /> : n}</span>;
}

