import { useState } from 'react';
import { Form, Head, Link, usePage } from '@inertiajs/react';
import { ArrowRight, Check, CheckCheck, Clock, UserRound } from 'lucide-react';
import { PageHeader } from '@/components/crm/page-header';
import { StatusPill } from '@/components/crm/status-badge';
import { Button } from '@/components/ui/button';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { formatDate } from '@/lib/format';
import type { CustomerChangeRequest, CustomerChangeRow } from '@/types';

type Props = {
    pending: CustomerChangeRequest[];
    recent: CustomerChangeRequest[];
    pendingCount: number;
    can: {
        review: boolean;
    };
};

/**
 * The queue of changes customers asked for from the ticket portal.
 *
 * A customer can save a correction whenever they like; this is where somebody
 * here checks it against what we hold and accepts or declines it. Declining
 * needs a reason, because the customer is shown it in the portal.
 */
export default function CustomerChangeRequests({
    pending,
    recent,
    pendingCount,
    can,
}: Props) {
    return (
        <>
            <Head title="Profile updates" />

            <div className="flex flex-col gap-6">
                <PageHeader
                    eyebrow={
                        <>
                            <UserRound className="size-3.5 text-solar" />
                            <span>
                                {pendingCount === 0
                                    ? 'Nothing waiting'
                                    : `${pendingCount} waiting for approval`}
                            </span>
                        </>
                    }
                    title="Profile updates"
                    description="Changes customers have saved from the ticket portal. Nothing reaches their record until somebody here approves it."
                    actions={
                        <Button asChild variant="outline" size="sm">
                            <Link href="/customers">
                                Customers
                                <ArrowRight className="size-4" />
                            </Link>
                        </Button>
                    }
                />

                {pending.length === 0 ? (
                    <div className="rounded-2xl bg-card p-8 text-center ring-1 ring-hairline">
                        <span className="mx-auto flex size-10 items-center justify-center rounded-full bg-emerald-500/10 text-emerald-600 dark:text-emerald-300">
                            <CheckCheck className="size-5" />
                        </span>
                        <p className="mt-3 text-sm font-medium">
                            Everything is up to date
                        </p>
                        <p className="mx-auto mt-1 max-w-md text-xs text-muted-foreground">
                            When a customer saves a change to their details, it
                            appears here for a person to check.
                        </p>
                    </div>
                ) : (
                    <div className="flex flex-col gap-4">
                        {pending.map((request) => (
                            <PendingCard
                                key={request.id}
                                request={request}
                                canReview={can.review}
                            />
                        ))}
                    </div>
                )}

                <section className="rounded-2xl bg-card ring-1 ring-hairline">
                    <div className="border-b border-hairline px-5 py-4">
                        <h2 className="text-sm font-semibold">
                            Recently reviewed
                        </h2>
                        <p className="mt-1 text-xs text-muted-foreground">
                            What was asked for, what was decided, and who
                            decided it.
                        </p>
                    </div>

                    {recent.length === 0 ? (
                        <p className="px-5 py-8 text-center text-xs text-muted-foreground">
                            No decisions yet.
                        </p>
                    ) : (
                        <Table>
                            <TableHeader>
                                <TableRow>
                                    <TableHead>Customer</TableHead>
                                    <TableHead>Changes</TableHead>
                                    <TableHead>Decision</TableHead>
                                    <TableHead>Reviewed</TableHead>
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {recent.map((request) => (
                                    <TableRow key={request.id}>
                                        <TableCell>
                                            {request.customer ? (
                                                <Link
                                                    href={`/customers/${request.customer.id}`}
                                                    className="font-medium hover:underline"
                                                >
                                                    {request.customer.name}
                                                </Link>
                                            ) : (
                                                '—'
                                            )}
                                            <p className="font-mono text-[11px] text-muted-foreground">
                                                {request.customer
                                                    ?.customer_number ?? ''}
                                            </p>
                                        </TableCell>
                                        <TableCell className="text-xs text-muted-foreground">
                                            {request.changes
                                                .map((change) => change.label)
                                                .join(', ') || '—'}
                                        </TableCell>
                                        <TableCell>
                                            <StatusPill
                                                tone={request.status.tone}
                                            >
                                                {request.status.label}
                                            </StatusPill>
                                            {request.review_note ? (
                                                <p className="mt-1 max-w-xs text-[11px] leading-snug text-muted-foreground">
                                                    {request.review_note}
                                                </p>
                                            ) : null}
                                        </TableCell>
                                        <TableCell className="whitespace-nowrap text-xs text-muted-foreground">
                                            {request.reviewed_at
                                                ? formatDate(request.reviewed_at)
                                                : '—'}
                                            {request.reviewer ? (
                                                <span className="block">
                                                    {request.reviewer.name}
                                                </span>
                                            ) : null}
                                        </TableCell>
                                    </TableRow>
                                ))}
                            </TableBody>
                        </Table>
                    )}
                </section>
            </div>
        </>
    );
}

/**
 * One change waiting on a decision: what the record says, what the customer
 * asked for, and the two answers available.
 */
function PendingCard({
    request,
    canReview,
}: {
    request: CustomerChangeRequest;
    canReview: boolean;
}) {
    const [declining, setDeclining] = useState(false);
    // A failed approval (for example an address that another account took while
    // the request was waiting) comes back here rather than disappearing.
    const { errors } = usePage<{ errors: Record<string, string> }>().props;

    return (
        <section className="rounded-2xl bg-card ring-1 ring-hairline">
            <div className="flex flex-wrap items-start justify-between gap-3 border-b border-hairline px-5 py-4">
                <div className="min-w-0">
                    <div className="flex flex-wrap items-center gap-2">
                        {request.customer ? (
                            <Link
                                href={`/customers/${request.customer.id}`}
                                className="text-sm font-semibold hover:underline"
                            >
                                {request.customer.name}
                            </Link>
                        ) : (
                            <span className="text-sm font-semibold">
                                Customer removed
                            </span>
                        )}
                        {request.customer ? (
                            <span className="font-mono text-[11px] text-muted-foreground">
                                {request.customer.customer_number}
                            </span>
                        ) : null}
                        <StatusPill tone={request.status.tone}>
                            {request.status.label}
                        </StatusPill>
                    </div>
                    <p className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground">
                        <Clock className="size-3.5" />
                        Saved {formatDate(request.submitted_at)}
                        {request.submitted_by
                            ? ` by ${request.submitted_by}`
                            : ''}
                        {request.customer?.phone
                            ? ` · ${request.customer.phone}`
                            : ''}
                    </p>
                </div>
            </div>

            <div className="px-5 py-4">
                <ChangeTable changes={request.changes} />

                {request.customer_note ? (
                    <p className="mt-3 rounded-lg bg-muted/60 px-3 py-2 text-xs leading-relaxed">
                        <span className="font-medium">
                            Customer&rsquo;s note:{' '}
                        </span>
                        {request.customer_note}
                    </p>
                ) : null}

                {canReview ? (
                    <div className="mt-4 flex flex-col gap-3">
                        {errors.review ? (
                            <p className="rounded-lg bg-red-500/10 px-3 py-2 text-xs text-red-700 dark:text-red-300">
                                {errors.review}
                            </p>
                        ) : null}

                        <div className="flex flex-wrap items-center gap-2">
                            <Form
                                action={`/customers/profile-changes/${request.id}/approve`}
                                method="post"
                            >
                                {({ processing }) => (
                                    <Button
                                        type="submit"
                                        size="sm"
                                        disabled={processing}
                                    >
                                        <Check />
                                        Approve and update
                                    </Button>
                                )}
                            </Form>

                            {declining ? null : (
                                <Button
                                    type="button"
                                    size="sm"
                                    variant="outline"
                                    onClick={() => setDeclining(true)}
                                >
                                    Decline
                                </Button>
                            )}
                        </div>

                        {declining ? (
                            <Form
                                action={`/customers/profile-changes/${request.id}/reject`}
                                method="post"
                                onSuccess={() => setDeclining(false)}
                                className="rounded-xl border border-hairline p-3"
                            >
                                {({ processing, errors }) => (
                                    <div className="flex flex-col gap-2">
                                        <label
                                            htmlFor={`review_note_${request.id}`}
                                            className="text-xs font-medium"
                                        >
                                            Why is it declined?
                                        </label>
                                        <p className="text-[11px] leading-snug text-muted-foreground">
                                            The customer sees this in the
                                            portal. Say what we need from them
                                            if the change can be made a
                                            different way.
                                        </p>
                                        <textarea
                                            id={`review_note_${request.id}`}
                                            name="review_note"
                                            required
                                            maxLength={1000}
                                            className="border-input min-h-20 w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]"
                                            placeholder="For example: we need the new address in writing from the account holder."
                                        />
                                        {errors.review_note ? (
                                            <p className="text-xs text-red-600 dark:text-red-400">
                                                {errors.review_note}
                                            </p>
                                        ) : null}
                                        {errors.review ? (
                                            <p className="text-xs text-red-600 dark:text-red-400">
                                                {errors.review}
                                            </p>
                                        ) : null}
                                        <div className="flex flex-wrap items-center gap-2">
                                            <Button
                                                type="submit"
                                                size="sm"
                                                variant="destructive"
                                                disabled={processing}
                                            >
                                                Decline this change
                                            </Button>
                                            <Button
                                                type="button"
                                                size="sm"
                                                variant="ghost"
                                                onClick={() =>
                                                    setDeclining(false)
                                                }
                                            >
                                                Cancel
                                            </Button>
                                        </div>
                                    </div>
                                )}
                            </Form>
                        ) : null}
                    </div>
                ) : (
                    <p className="mt-4 text-xs text-muted-foreground">
                        You can view this, but editing customers is what
                        approves or declines it.
                    </p>
                )}
            </div>
        </section>
    );
}

/** Current value against the requested one, field by field. */
function ChangeTable({ changes }: { changes: CustomerChangeRow[] }) {
    if (changes.length === 0) {
        return (
            <p className="text-xs text-muted-foreground">
                No fields differ from the record.
            </p>
        );
    }

    return (
        <dl className="divide-y divide-hairline overflow-hidden rounded-xl ring-1 ring-hairline">
            {changes.map((change) => (
                <div
                    key={change.field}
                    className="grid gap-1 px-3 py-2 text-xs sm:grid-cols-[10rem_1fr] sm:items-baseline sm:gap-4"
                >
                    <dt className="font-medium text-muted-foreground">
                        {change.label}
                    </dt>
                    <dd className="flex flex-wrap items-baseline gap-2">
                        <span className="text-muted-foreground line-through">
                            {change.from ?? '—'}
                        </span>
                        <span aria-hidden className="text-muted-foreground">
                            →
                        </span>
                        <span className="font-medium">{change.to ?? '—'}</span>
                    </dd>
                </div>
            ))}
        </dl>
    );
}
