// Components that take every color from the token roles in tokens.css.
// From https://auricartisan.com/integrations/react-tokens/ - CC0 1.0.
// Each state has a word and an icon as well as a color, and every control has a visible focus ring.
import { useId } from "react";
import { useTheme } from "./theme.jsx";

const ICONS = {
    success: <path d="M4 10.5 8 14.5 16 6.5" />,
    warning: <><path d="M10 3 18 17H2Z" /><path d="M10 8v4M10 14.5v.5" /></>,
    danger: <path d="M5 5l10 10M15 5 5 15" />,
    info: <><circle cx="10" cy="10" r="7.5" /><path d="M10 9v5M10 6v.5" /></>,
};
const WORDS = { success: "Success", warning: "Warning", danger: "Error", info: "Note" };

export function Icon({ tone }) {
    return (
        <svg className="icon" viewBox="0 0 20 20" aria-hidden="true" focusable="false">{ICONS[tone]}</svg>
    );
}

export function Button({ variant = "primary", ...props }) {
    return <button type="button" className={`button button--${variant}`} {...props} />;
}

/** A message announced without moving focus: role="status", rendered empty first. A message that is
    there from the start is not news, so live={false} leaves the role off. */
export function StatusMessage({ tone, children, live = true }) {
    return (
        <div className={`message message--${tone}`} role={live ? (tone === "danger" ? "alert" : "status") : undefined}>
            {children ? <><Icon tone={tone} /><p><strong>{WORDS[tone]}:</strong> {children}</p></> : null}
        </div>
    );
}

export function Field({ label, error, hint, ...props }) {
    const id = useId();
    const describedBy = [hint && `${id}-hint`, error && `${id}-error`].filter(Boolean).join(" ") || undefined;
    return (
        <div className="field">
            <label htmlFor={id}>{label}</label>
            {hint ? <p className="field__hint" id={`${id}-hint`}>{hint}</p> : null}
            <input id={id} aria-invalid={error ? "true" : undefined} aria-describedby={describedBy} {...props} />
            {error ? <p className="field__error" id={`${id}-error`}><Icon tone="danger" />{error}</p> : null}
        </div>
    );
}

export function ThemeSwitch() {
    const { choice, setChoice } = useTheme();
    return (
        <fieldset className="theme-switch">
            <legend>Theme</legend>
            {["system", "light", "dark"].map((value) => (
                <label key={value}>
                    <input type="radio" name="theme" value={value} checked={choice === value} onChange={() => setChoice(value)} />
                    <span>{value === "system" ? "Match the system" : value === "light" ? "Light" : "Dark"}</span>
                </label>
            ))}
        </fieldset>
    );
}
