import { Link, router, useForm } from '@inertiajs/react';
import { Clock, Eye, EyeOff, ExternalLink, Sparkles, Star, X } from 'lucide-react';
import { CopyText } from '@/components/CopyText';
import { embedCode } from '@/components/EmbedCode';
import { PageHeader } from '@/components/PageHeader';
import { Pagination } from '@/components/Pagination';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardBody, CardHeader } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Input, Select } from '@/components/ui/input';
import { Field, FieldError } from '@/components/ui/label';
import AppLayout from '@/layouts/AppLayout';
import { dateTime } from '@/lib/format';
import { cn } from '@/lib/utils';
import type { Paginated, SharedProps } from '@/types';
import { usePage } from '@inertiajs/react';

type Review = {
    id: number; status: string; status_label: string; rating: number | null; comment: string | null; name: string | null; role: string | null; email: string | null;
    featured: boolean; quote: { id: number; number: string; title: string } | null; submitted_at: string | null; due_at: string | null; sent_at: string | null; google_clicked: boolean;
};
type Props = {
    reviews: Paginated<Review>; tab: string; counts: Record<string, number>; stats: { published: number; average: number; featured: number };
    settings: { enabled: boolean; google_review_url: string | null; delay_days: number }; canModerate: boolean; publicUrl: string; maxFeatured: number; window: string;
};

const TABS = [['moderate', 'To moderate', ['submitted']], ['approved', 'Published', ['approved']], ['hidden', 'Hidden', ['hidden']], ['requests', 'Requests', ['requested', 'sent']]] as const;

function Stars({ n }: { n: number }) {
    return <span className="inline-flex text-accent" aria-label={`${n} out of 5 stars`} role="img">{[1, 2, 3, 4, 5].map((i) => <Star key={i} className="h-4 w-4" fill={i <= n ? 'currentColor' : 'none'} strokeWidth={1.5} aria-hidden />)}</span>;
}

/** Reviews: moderation, the best 3 featured on proposals, the request queue, and settings. */
export default function ReviewsIndex(props: Props) {
    const { reviews, tab, counts, stats, canModerate } = props;
    const errors = usePage<SharedProps & { errors: Record<string, string> }>().props.errors;
    const act = (id: number, action: string) => router.post(`/reviews/${id}/moderate`, { action }, { preserveScroll: true });
    const count = (statuses: readonly string[]) => statuses.reduce((a, s) => a + (counts[s] ?? 0), 0);

    return (
        <AppLayout title="Reviews">
            <PageHeader title="Reviews" description={`Clients are asked for a review when a quote is marked Completed, ${props.window}. Publish the good ones and feature the best ${props.maxFeatured} on proposals.`} />
            <div className="mb-4 grid gap-4 sm:grid-cols-3">
                <Card className="p-4"><div className="text-xs text-ink-muted">Published reviews</div><div className="mt-1 text-2xl font-medium" data-testid="reviews-published">{stats.published}</div></Card>
                <Card className="p-4"><div className="text-xs text-ink-muted">Average rating</div><div className="mt-1 flex items-center gap-2 text-2xl font-medium">{stats.published ? stats.average.toFixed(1) : '—'} {stats.published > 0 && <Stars n={Math.round(stats.average)} />}</div></Card>
                <Card className="p-4"><div className="text-xs text-ink-muted">Featured on proposals</div><div className="mt-1 text-2xl font-medium">{stats.featured} / {props.maxFeatured}</div></Card>
            </div>
            <div className="grid gap-6 lg:grid-cols-[1fr_22rem]">
                <div className="min-w-0">
                    <div className="mb-3 flex flex-wrap gap-1 rounded-[var(--radius-card)] bg-surface p-1.5 shadow-card" role="tablist">
                        {TABS.map(([k, label, st]) => (
                            <Link key={k} href={`/reviews?tab=${k}`} role="tab" aria-selected={tab === k} preserveScroll data-testid={`reviews-tab-${k}`}
                                className={cn('rounded-[5px] px-3 py-1.5 text-sm font-medium', tab === k ? 'bg-accent-fill text-accent-ink' : 'hover:bg-accent-soft')}>
                                {label} <span className="ml-1 text-xs opacity-75">{count(st)}</span>
                            </Link>
                        ))}
                    </div>
                    <FieldError message={errors?.featured} />
                    <div className="grid gap-3">
                        {reviews.data.length === 0 && <Card className="px-6 py-12 text-center text-sm text-ink-muted" data-testid="reviews-empty">Nothing here yet.</Card>}
                        {reviews.data.map((r) => (
                            <Card key={r.id} className="p-4" data-testid="review-card">
                                <div className="flex flex-wrap items-start gap-3">
                                    <div className="min-w-0 flex-1">
                                        <div className="flex flex-wrap items-center gap-2">
                                            {r.rating ? <Stars n={r.rating} /> : null}
                                            <span className="font-medium">{r.name ?? r.email}</span>
                                            {r.role && <span className="text-sm text-ink-muted">{r.role}</span>}
                                            {r.featured && <Badge className="bg-accent-soft text-link-hover"><Sparkles className="mr-1 h-3 w-3" /> Featured</Badge>}
                                            {tab === 'requests' && <Badge className="bg-stone-100 text-stone-700">{r.status_label}</Badge>}
                                        </div>
                                        {r.comment && <p className="mt-2 whitespace-pre-wrap text-sm">{r.comment}</p>}
                                        <p className="mt-2 text-xs text-ink-muted">
                                            {r.quote && <Link href={`/quotes/${r.quote.id}/edit`} className="text-link underline">{r.quote.number}</Link>}
                                            {r.quote && ' · '}
                                            {r.submitted_at ? `Reviewed ${dateTime(r.submitted_at)}` : r.sent_at ? `Request sent ${dateTime(r.sent_at)} to ${r.email}` : r.due_at ? <><Clock className="mr-0.5 inline h-3 w-3" /> Sends {dateTime(r.due_at)} to {r.email}</> : null}
                                            {r.google_clicked && ' · Went on to Google'}
                                        </p>
                                    </div>
                                    {canModerate && (
                                        <div className="flex flex-wrap gap-1.5">
                                            {['submitted', 'hidden'].includes(r.status) && <Button size="sm" onClick={() => act(r.id, 'approve')} data-testid="review-approve"><Eye className="h-3.5 w-3.5" /> Publish</Button>}
                                            {['submitted', 'approved'].includes(r.status) && <Button size="sm" variant="secondary" onClick={() => act(r.id, 'hide')} data-testid="review-hide"><EyeOff className="h-3.5 w-3.5" /> Hide</Button>}
                                            {r.status === 'approved' && (r.featured
                                                ? <Button size="sm" variant="secondary" onClick={() => act(r.id, 'unfeature')}>Unfeature</Button>
                                                : <Button size="sm" variant="secondary" onClick={() => act(r.id, 'feature')} data-testid="review-feature"><Sparkles className="h-3.5 w-3.5" /> Feature</Button>)}
                                            {['requested', 'sent'].includes(r.status) && <Button size="sm" variant="ghost" onClick={() => act(r.id, 'cancel')}><X className="h-3.5 w-3.5" /> Cancel</Button>}
                                        </div>
                                    )}
                                </div>
                            </Card>
                        ))}
                    </div>
                    <Pagination page={reviews} />
                </div>
                <div className="grid content-start gap-6">
                    <SettingsCard {...props} />
                    <Card>
                        <CardHeader title="Public page & embed" />
                        <CardBody className="grid gap-3 text-sm">
                            <div><div className="mb-1 font-medium">Reviews page</div><CopyText value={props.publicUrl} testId="reviews-public-url" />
                                <a href={props.publicUrl} target="_blank" rel="noopener" className="mt-1 inline-flex items-center gap-1 text-xs text-link underline">Open <ExternalLink className="h-3 w-3" /></a></div>
                            <div><div className="mb-1 font-medium">Embed on your website</div><CopyText multiline value={embedCode(`${props.publicUrl}?embed=1`, 'spin-reviews', 'Client reviews', 320)} /></div>
                            <p className="text-xs text-ink-muted">Only published reviews appear. Add a Testimonial block set to “Featured client reviews” in a template to show the featured ones on proposals.</p>
                        </CardBody>
                    </Card>
                </div>
            </div>
        </AppLayout>
    );
}

function SettingsCard({ settings, canModerate, window }: Props) {
    const f = useForm({ enabled: settings.enabled, google_review_url: settings.google_review_url ?? '', delay_days: settings.delay_days });
    return (
        <Card>
            <CardHeader title="Review requests" />
            <CardBody>
                <form className="grid gap-3" onSubmit={(e) => { e.preventDefault(); f.transform((d) => ({ ...d, google_review_url: d.google_review_url || null })); f.put('/reviews/settings', { preserveScroll: true }); }}>
                    <Checkbox label="Ask for a review when a quote is marked Completed" checked={f.data.enabled} disabled={!canModerate} onChange={(e) => f.setData('enabled', e.target.checked)} data-testid="reviews-enabled" />
                    <Field label="Wait before asking" htmlFor="rv-delay" hint={`Then sent in the next window: ${window}.`}>
                        <Select id="rv-delay" value={f.data.delay_days} disabled={!canModerate} onChange={(e) => f.setData('delay_days', Number(e.target.value))}>
                            {[0, 1, 2, 3, 5, 7, 14, 30].map((d) => <option key={d} value={d}>{d === 0 ? 'No wait' : `${d} day${d > 1 ? 's' : ''}`}</option>)}
                        </Select>
                    </Field>
                    <Field label="Google review link" htmlFor="rv-google" error={f.errors.google_review_url} hint="4–5 star reviewers are asked to post on Google too. Find it in your Google Business Profile → Ask for reviews.">
                        <Input id="rv-google" type="url" placeholder="https://g.page/r/…/review" value={f.data.google_review_url} disabled={!canModerate} onChange={(e) => f.setData('google_review_url', e.target.value)} data-testid="google-review-url" />
                    </Field>
                    {canModerate && <div><Button disabled={f.processing} data-testid="save-review-settings">Save</Button></div>}
                    <p className="text-xs text-ink-muted">The email uses the “Review request” template in Settings → Emails.</p>
                </form>
            </CardBody>
        </Card>
    );
}
