import { Badge } from '@/components/ui/badge';
import { cn } from '@/lib/utils';
import { toneClasses } from './tone';

export { toneClasses as toneClassName } from './tone';

/**
 * The default way to show a status in a list or table: a coloured dot and the
 * label. Quiet enough to sit in a dense table, precise enough to scan.
 */
export function StatusDot({
    tone,
    className,
    pulse = false,
}: {
    tone: string | null | undefined;
    className?: string;
    pulse?: boolean;
}) {
    return (
        <span
            aria-hidden
            className={cn(
                'inline-block size-1.5 shrink-0 rounded-full',
                toneClasses(tone).dot,
                pulse && 'animate-pulse',
                className,
            )}
        />
    );
}

export function StatusLabel({
    tone,
    children,
    className,
    quiet = false,
}: {
    tone: string | null | undefined;
    children: React.ReactNode;
    className?: string;
    quiet?: boolean;
}) {
    return (
        <span
            className={cn(
                'inline-flex items-center gap-1.5 text-sm font-medium whitespace-nowrap',
                quiet ? 'text-muted-foreground' : toneClasses(tone).text,
                className,
            )}
        >
            <StatusDot tone={tone} className={quiet ? 'opacity-50' : undefined} />
            {children}
        </span>
    );
}

/**
 * The stronger treatment, for a page header or a detail panel where the status
 * is the headline rather than a column value.
 */
export function StatusPill({
    tone,
    children,
    className,
}: {
    tone: string | null | undefined;
    children: React.ReactNode;
    className?: string;
}) {
    return (
        <Badge
            variant="outline"
            className={cn(
                'gap-1.5 border-transparent px-2 py-0.5 font-medium whitespace-nowrap',
                toneClasses(tone).pill,
                className,
            )}
        >
            <StatusDot tone={tone} className="size-1.5" />
            {children}
        </Badge>
    );
}

/**
 * The job's position in the installation pipeline.
 */
export function JobStatusBadge({
    status,
    variant = 'label',
    className,
}: {
    status: { label: string; color: string; is_terminal?: boolean };
    variant?: 'label' | 'pill';
    className?: string;
}) {
    if (variant === 'pill') {
        return (
            <StatusPill tone={status.color} className={className}>
                {status.label}
            </StatusPill>
        );
    }

    return (
        <StatusLabel
            tone={status.color}
            quiet={status.is_terminal}
            className={className}
        >
            {status.label}
        </StatusLabel>
    );
}

export function PriorityBadge({
    priority,
}: {
    priority: { label: string; color: string };
}) {
    return (
        <StatusPill tone={priority.color} className="text-[11px]">
            {priority.label}
        </StatusPill>
    );
}

/**
 * Grid connection state. Approved states are green so staff can see at a
 * glance whether a job is allowed to be installed.
 */
export function GridStatusBadge({
    status,
    variant = 'label',
}: {
    status: { label: string; is_approved: boolean };
    variant?: 'label' | 'pill';
}) {
    const tone = status.is_approved ? 'success' : 'warning';

    return variant === 'pill' ? (
        <StatusPill tone={tone}>{status.label}</StatusPill>
    ) : (
        <StatusLabel tone={tone}>{status.label}</StatusLabel>
    );
}

export function InspectionBadge({
    inspection,
    variant = 'label',
}: {
    inspection: {
        label: string;
        is_passed?: boolean;
        blocks_energising?: boolean;
    };
    variant?: 'label' | 'pill';
}) {
    const tone = inspection.is_passed
        ? 'success'
        : inspection.blocks_energising
          ? 'danger'
          : 'slate';

    return variant === 'pill' ? (
        <StatusPill tone={tone}>{inspection.label}</StatusPill>
    ) : (
        <StatusLabel tone={tone}>{inspection.label}</StatusLabel>
    );
}

export function StcBadge({
    status,
    variant = 'label',
}: {
    status: { label: string; is_open: boolean };
    variant?: 'label' | 'pill';
}) {
    const tone = status.is_open ? 'warning' : 'success';

    return variant === 'pill' ? (
        <StatusPill tone={tone}>{status.label}</StatusPill>
    ) : (
        <StatusLabel tone={tone}>{status.label}</StatusLabel>
    );
}

/**
 * Small state flag for state-specific rules, for example Victoria needing an
 * independent electrical inspection.
 */
export function RuleFlag({
    children,
    tone = 'info',
    className,
}: {
    children: React.ReactNode;
    tone?: string;
    className?: string;
}) {
    return (
        <StatusPill tone={tone} className={cn('text-[11px]', className)}>
            {children}
        </StatusPill>
    );
}
