/**
 * The one place a colour name becomes Tailwind classes.
 *
 * The backend sends a colour name for every status, priority and state
 * (see App\Enums\*::color()), and the design system exposes four treatments
 * for each: a dot for tables and lists, a soft pill for headers and detail
 * views, a solid-ish bar for progress, and a text colour for figures.
 *
 * Class strings are written out in full, never composed at runtime, because
 * Tailwind only ships classes it can see in the source.
 */

export type Tone =
    | 'slate'
    | 'blue'
    | 'indigo'
    | 'violet'
    | 'amber'
    | 'orange'
    | 'cyan'
    | 'yellow'
    | 'red'
    | 'teal'
    | 'emerald'
    | 'green'
    | 'rose'
    | 'solar'
    | 'success'
    | 'warning'
    | 'danger'
    | 'info';

export type ToneClasses = {
    /** A filled dot, the default marker beside a status label. */
    dot: string;
    /** Soft pill: tinted surface, hairline edge, readable text. */
    pill: string;
    /** Icon chip: a tinted square behind a small icon. */
    soft: string;
    /** Progress bar or left rail. */
    bar: string;
    /** Text and figures. */
    text: string;
};

const tones: Record<Tone, ToneClasses> = {
    slate: {
        dot: 'bg-slate-400 dark:bg-slate-500',
        pill: 'bg-slate-500/10 text-slate-700 ring-1 ring-inset ring-slate-500/20 dark:text-slate-300 dark:bg-slate-400/10 dark:ring-slate-400/20',
        soft: 'bg-slate-500/10 text-slate-600 dark:text-slate-300',
        bar: 'bg-slate-400 dark:bg-slate-500',
        text: 'text-slate-700 dark:text-slate-300',
    },
    blue: {
        dot: 'bg-blue-500',
        pill: 'bg-blue-500/10 text-blue-700 ring-1 ring-inset ring-blue-500/20 dark:text-blue-300 dark:bg-blue-400/10 dark:ring-blue-400/25',
        soft: 'bg-blue-500/10 text-blue-600 dark:text-blue-300',
        bar: 'bg-blue-500',
        text: 'text-blue-700 dark:text-blue-300',
    },
    indigo: {
        dot: 'bg-indigo-500',
        pill: 'bg-indigo-500/10 text-indigo-700 ring-1 ring-inset ring-indigo-500/20 dark:text-indigo-300 dark:bg-indigo-400/10 dark:ring-indigo-400/25',
        soft: 'bg-indigo-500/10 text-indigo-600 dark:text-indigo-300',
        bar: 'bg-indigo-500',
        text: 'text-indigo-700 dark:text-indigo-300',
    },
    violet: {
        dot: 'bg-violet-500',
        pill: 'bg-violet-500/10 text-violet-700 ring-1 ring-inset ring-violet-500/20 dark:text-violet-300 dark:bg-violet-400/10 dark:ring-violet-400/25',
        soft: 'bg-violet-500/10 text-violet-600 dark:text-violet-300',
        bar: 'bg-violet-500',
        text: 'text-violet-700 dark:text-violet-300',
    },
    amber: {
        dot: 'bg-amber-500',
        pill: 'bg-amber-500/12 text-amber-800 ring-1 ring-inset ring-amber-500/25 dark:text-amber-300 dark:bg-amber-400/10 dark:ring-amber-400/25',
        soft: 'bg-amber-500/12 text-amber-700 dark:text-amber-300',
        bar: 'bg-amber-500',
        text: 'text-amber-800 dark:text-amber-300',
    },
    orange: {
        dot: 'bg-orange-500',
        pill: 'bg-orange-500/12 text-orange-800 ring-1 ring-inset ring-orange-500/25 dark:text-orange-300 dark:bg-orange-400/10 dark:ring-orange-400/25',
        soft: 'bg-orange-500/12 text-orange-700 dark:text-orange-300',
        bar: 'bg-orange-500',
        text: 'text-orange-800 dark:text-orange-300',
    },
    yellow: {
        dot: 'bg-yellow-400',
        pill: 'bg-yellow-400/15 text-yellow-800 ring-1 ring-inset ring-yellow-500/25 dark:text-yellow-200 dark:bg-yellow-400/10 dark:ring-yellow-400/25',
        soft: 'bg-yellow-400/15 text-yellow-700 dark:text-yellow-200',
        bar: 'bg-yellow-400',
        text: 'text-yellow-800 dark:text-yellow-200',
    },
    red: {
        dot: 'bg-red-500',
        pill: 'bg-red-500/10 text-red-700 ring-1 ring-inset ring-red-500/20 dark:text-red-300 dark:bg-red-400/10 dark:ring-red-400/25',
        soft: 'bg-red-500/10 text-red-600 dark:text-red-300',
        bar: 'bg-red-500',
        text: 'text-red-700 dark:text-red-300',
    },
    cyan: {
        dot: 'bg-cyan-500',
        pill: 'bg-cyan-500/10 text-cyan-700 ring-1 ring-inset ring-cyan-500/20 dark:text-cyan-300 dark:bg-cyan-400/10 dark:ring-cyan-400/25',
        soft: 'bg-cyan-500/10 text-cyan-600 dark:text-cyan-300',
        bar: 'bg-cyan-500',
        text: 'text-cyan-700 dark:text-cyan-300',
    },
    teal: {
        dot: 'bg-teal-500',
        pill: 'bg-teal-500/10 text-teal-700 ring-1 ring-inset ring-teal-500/20 dark:text-teal-300 dark:bg-teal-400/10 dark:ring-teal-400/25',
        soft: 'bg-teal-500/10 text-teal-600 dark:text-teal-300',
        bar: 'bg-teal-500',
        text: 'text-teal-700 dark:text-teal-300',
    },
    emerald: {
        dot: 'bg-emerald-500',
        pill: 'bg-emerald-500/10 text-emerald-700 ring-1 ring-inset ring-emerald-500/20 dark:text-emerald-300 dark:bg-emerald-400/10 dark:ring-emerald-400/25',
        soft: 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-300',
        bar: 'bg-emerald-500',
        text: 'text-emerald-700 dark:text-emerald-300',
    },
    green: {
        dot: 'bg-green-500',
        pill: 'bg-green-500/10 text-green-700 ring-1 ring-inset ring-green-500/20 dark:text-green-300 dark:bg-green-400/10 dark:ring-green-400/25',
        soft: 'bg-green-500/10 text-green-600 dark:text-green-300',
        bar: 'bg-green-500',
        text: 'text-green-700 dark:text-green-300',
    },
    rose: {
        dot: 'bg-rose-500',
        pill: 'bg-rose-500/10 text-rose-700 ring-1 ring-inset ring-rose-500/20 dark:text-rose-300 dark:bg-rose-400/10 dark:ring-rose-400/25',
        soft: 'bg-rose-500/10 text-rose-600 dark:text-rose-300',
        bar: 'bg-rose-500',
        text: 'text-rose-700 dark:text-rose-300',
    },
    solar: {
        dot: 'bg-solar',
        pill: 'bg-solar-soft text-solar-ink ring-1 ring-inset ring-solar/30',
        soft: 'bg-solar-soft text-solar-ink',
        bar: 'bg-solar',
        text: 'text-solar-ink',
    },
    success: {
        dot: 'bg-success',
        pill: 'bg-success-soft text-success ring-1 ring-inset ring-success/25',
        soft: 'bg-success-soft text-success',
        bar: 'bg-success',
        text: 'text-success',
    },
    warning: {
        dot: 'bg-warning',
        pill: 'bg-warning-soft text-warning ring-1 ring-inset ring-warning/30',
        soft: 'bg-warning-soft text-warning',
        bar: 'bg-warning',
        text: 'text-warning',
    },
    danger: {
        dot: 'bg-danger',
        pill: 'bg-danger-soft text-danger ring-1 ring-inset ring-danger/25',
        soft: 'bg-danger-soft text-danger',
        bar: 'bg-danger',
        text: 'text-danger',
    },
    info: {
        dot: 'bg-info',
        pill: 'bg-info-soft text-info ring-1 ring-inset ring-info/25',
        soft: 'bg-info-soft text-info',
        bar: 'bg-info',
        text: 'text-info',
    },
};

/** Anything the backend sends that we do not know about reads as neutral. */
export function toneClasses(tone: string | null | undefined): ToneClasses {
    if (tone && tone in tones) {
        return tones[tone as Tone];
    }

    return tones.slate;
}

/**
 * A muted treatment for a status we only want to whisper, for example a
 * closed job in a list of active work.
 */
export function quietToneClasses(
    tone: string | null | undefined,
): ToneClasses {
    const classes = toneClasses(tone);

    return {
        ...classes,
        dot: classes.dot,
        pill: 'bg-transparent text-muted-foreground ring-1 ring-inset ring-border',
        text: 'text-muted-foreground',
    };
}

/** The colour names the backend can send, for typing component props. */
export const TONES: Tone[] = Object.keys(tones) as Tone[];
