import type { LucideIcon } from 'lucide-react';
import { cn } from '@/lib/utils';
import { toneClasses } from './tone';

export function PageHeader({
    title,
    description,
    eyebrow,
    actions,
    className,
}: {
    title: string;
    description?: string | null;
    eyebrow?: React.ReactNode;
    actions?: React.ReactNode;
    className?: string;
}) {
    return (
        <div
            className={cn(
                'flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between',
                className,
            )}
        >
            <div className="min-w-0 space-y-1.5">
                {eyebrow ? (
                    <div className="text-muted-foreground flex items-center gap-2 text-xs font-medium">
                        {eyebrow}
                    </div>
                ) : null}
                <h1 className="text-2xl font-semibold tracking-tight text-balance">
                    {title}
                </h1>
                {description ? (
                    <p className="text-muted-foreground max-w-3xl text-sm">
                        {description}
                    </p>
                ) : null}
            </div>
            {actions ? (
                <div className="flex shrink-0 flex-wrap items-center gap-2">
                    {actions}
                </div>
            ) : null}
        </div>
    );
}

/**
 * A section of the page. `flush` drops the body padding so a table can run to
 * the card edge, which is what most CRM panels want.
 */
export function SectionCard({
    title,
    description,
    actions,
    icon: Icon,
    tone,
    flush = false,
    className,
    bodyClassName,
    id,
    children,
}: {
    title: string;
    description?: string | null;
    actions?: React.ReactNode;
    icon?: LucideIcon;
    tone?: string;
    flush?: boolean;
    className?: string;
    bodyClassName?: string;
    id?: string;
    children: React.ReactNode;
}) {
    return (
        <section
            id={id}
            className={cn(
                'bg-card shadow-card scroll-mt-24 rounded-xl ring-1 ring-hairline',
                className,
            )}
        >
            <header className="flex flex-col gap-2 px-5 py-4 sm:flex-row sm:items-center sm:justify-between">
                <div className="flex min-w-0 items-start gap-3">
                    {Icon ? (
                        <span
                            className={cn(
                                'mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg',
                                toneClasses(tone).soft,
                            )}
                        >
                            <Icon className="size-4" />
                        </span>
                    ) : null}
                    <div className="min-w-0">
                        <h2 className="text-sm font-semibold tracking-tight">
                            {title}
                        </h2>
                        {description ? (
                            <p className="text-muted-foreground mt-0.5 text-xs leading-relaxed">
                                {description}
                            </p>
                        ) : null}
                    </div>
                </div>
                {actions ? (
                    <div className="flex flex-wrap items-center gap-2">
                        {actions}
                    </div>
                ) : null}
            </header>
            <div
                className={cn(
                    !flush && 'px-5 pb-5',
                    flush && 'pb-1',
                    bodyClassName,
                )}
            >
                {children}
            </div>
        </section>
    );
}

export function DetailRow({
    label,
    value,
    className,
}: {
    label: string;
    value: React.ReactNode;
    className?: string;
}) {
    return (
        <div className={cn('min-w-0', className)}>
            <dt className="crm-label">{label}</dt>
            <dd className="mt-1 text-sm break-words">
                {value === null || value === undefined || value === '' ? (
                    <span className="text-muted-foreground/60">—</span>
                ) : (
                    value
                )}
            </dd>
        </div>
    );
}

/**
 * A grid of labelled values with hairlines, for the detail half of a page.
 */
export function KeyValueGrid({
    items,
    columns = 2,
    className,
}: {
    items: Array<{ label: string; value: React.ReactNode }>;
    columns?: 1 | 2 | 3 | 4;
    className?: string;
}) {
    const columnClass = {
        1: 'sm:grid-cols-1',
        2: 'sm:grid-cols-2',
        3: 'sm:grid-cols-2 lg:grid-cols-3',
        4: 'sm:grid-cols-2 lg:grid-cols-4',
    }[columns];

    return (
        <dl
            className={cn(
                'grid grid-cols-1 gap-x-8 gap-y-4',
                columnClass,
                className,
            )}
        >
            {items.map((item) => (
                <DetailRow
                    key={item.label}
                    label={item.label}
                    value={item.value}
                />
            ))}
        </dl>
    );
}

/**
 * A message that matters: a gate, a blocker, a compliance rule. The tone
 * decides whether it reads as information, a warning or a hard stop.
 */
export function Callout({
    title,
    children,
    tone = 'info',
    icon: Icon,
    actions,
    className,
}: {
    title?: string;
    children?: React.ReactNode;
    tone?: string;
    icon?: LucideIcon;
    actions?: React.ReactNode;
    className?: string;
}) {
    const classes = toneClasses(tone);

    return (
        <div
            className={cn(
                'flex items-start gap-3 rounded-xl px-4 py-3 ring-1 ring-inset',
                classes.pill,
                className,
            )}
        >
            {Icon ? (
                <Icon className="mt-0.5 size-4 shrink-0" aria-hidden />
            ) : (
                <span
                    aria-hidden
                    className={cn(
                        'mt-1.5 size-1.5 shrink-0 rounded-full',
                        classes.dot,
                    )}
                />
            )}
            <div className="min-w-0 flex-1 space-y-1">
                {title ? (
                    <p className="text-sm font-semibold">{title}</p>
                ) : null}
                {children ? (
                    <div className="text-sm opacity-90">{children}</div>
                ) : null}
            </div>
            {actions ? (
                <div className="flex shrink-0 items-center gap-2">
                    {actions}
                </div>
            ) : null}
        </div>
    );
}

export function EmptyState({
    title,
    description,
    action,
    icon: Icon,
    className,
}: {
    title: string;
    description?: string;
    action?: React.ReactNode;
    icon?: LucideIcon;
    className?: string;
}) {
    return (
        <div
            className={cn(
                'flex flex-col items-center justify-center gap-2 rounded-xl px-6 py-10 text-center',
                className,
            )}
        >
            {Icon ? (
                <span className="bg-muted text-muted-foreground mb-1 flex size-10 items-center justify-center rounded-full">
                    <Icon className="size-5" />
                </span>
            ) : null}
            <p className="text-sm font-medium">{title}</p>
            {description ? (
                <p className="text-muted-foreground max-w-md text-xs leading-relaxed">
                    {description}
                </p>
            ) : null}
            {action ? <div className="mt-2">{action}</div> : null}
        </div>
    );
}

/**
 * A row of small figures under a page title, for context that is worth
 * showing but not worth a tile of its own.
 */
export function MetaStrip({
    items,
    className,
}: {
    items: Array<{ label: string; value: React.ReactNode; tone?: string }>;
    className?: string;
}) {
    return (
        <div
            className={cn(
                'flex flex-wrap items-center gap-x-5 gap-y-1.5 text-xs',
                className,
            )}
        >
            {items.map((item) => (
                <span key={item.label} className="flex items-center gap-1.5">
                    <span className="text-muted-foreground/80">
                        {item.label}
                    </span>
                    <span
                        className={cn(
                            'crm-num font-medium',
                            item.tone ? toneClasses(item.tone).text : undefined,
                        )}
                    >
                        {item.value}
                    </span>
                </span>
            ))}
        </div>
    );
}
