import { Check, Info } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Combobox } from '@/components/ui/combobox';
import { Slider } from '@/components/ui/slider';
import { SegmentedControl } from '@/components/ui/segmented-control';
import { TogglePill } from '@/components/ui/toggle-pill';
import { useDensity } from '@/hooks/use-density';
import type { Density } from '@/hooks/use-density';
import { useLogChipColorMode, type LogChipColorMode } from '@/hooks/use-log-chip-color-mode';
import { useTopNavLabels } from '@/hooks/use-top-nav-labels';
import { useTopNavAlign, type TopNavAlign } from '@/hooks/use-top-nav-align';
import { useTopNavMode, type TopNavMode } from '@/hooks/use-top-nav-mode';
import { useTopNavQuickLinks, MAX_QUICK_LINKS } from '@/hooks/use-top-nav-quick-links';
import { getAppNavItem } from '@/lib/navigation/appNavRegistry';
import type { NavDestination } from '@/lib/navigation/appNavRegistry';
import type { ActiveView } from '@/lib/router/routeTypes';
import {
    useTheme, activeVisualStyle, THEME_MODE_OPTIONS, ACCENTS, CONTRAST, BORDER_BOOST, GLOW, TYPE_SCALE,
    type VisualStyle, type HeadingStyle, type ChartStyle,
} from '@/hooks/use-theme';
import { AccentPicker } from '@/components/theme/AccentPicker';
import { ThemePreview } from '@/components/theme/ThemePreview';
import { TypeChips } from '@/components/theme/TypeChips';
import { UI_FONT_OPTIONS, MONO_FONT_OPTIONS } from '@/components/theme/typeOptions';
import { SettingsSection } from './SettingsSection';
import { SettingsField } from './SettingsField';
import { SettingsActions, SettingsSecondaryButton } from './SettingsActions';
import { SettingsCallout } from './SettingsCallout';

const DENSITY_OPTIONS: { value: Density; label: string }[] = [
    { value: 'comfortable', label: 'Comfortable' },
    { value: 'compact', label: 'Compact' },
];

const DENSITY_DESCRIPTIONS: Record<Density, string> = {
    comfortable: 'Default spacing. Roomy rows for review and orientation.',
    compact: 'Tighter rows and tiles. Fits more on screen for dense dashboards.',
};

const TOP_NAV_ALIGN_OPTIONS: { value: TopNavAlign; label: string }[] = [
    { value: 'left', label: 'Left' },
    { value: 'center', label: 'Center' },
];

const TOP_NAV_MODE_OPTIONS: { value: TopNavMode; label: string }[] = [
    { value: 'classic', label: 'Classic bar' },
    { value: 'smart', label: 'Smart bar' },
    { value: 'compact', label: 'Compact launcher' },
];

const CHART_STYLE_OPTIONS: { value: ChartStyle; label: string }[] = [
    { value: 'muted', label: 'Muted' },
    { value: 'heat', label: 'Heat' },
    { value: 'signature', label: 'Signature' },
];

const HEADING_STYLE_OPTIONS: { value: HeadingStyle; label: string }[] = [
    { value: 'clean', label: 'Clean' },
    { value: 'signature', label: 'Signature' },
];

const CHIP_COLOR_OPTIONS: { value: LogChipColorMode; label: string }[] = [
    { value: 'unified', label: 'Unified' },
    { value: 'per-service', label: 'Per service' },
];

const fmtSigned = (v: number) => `${v > 0 ? '+' : ''}${v.toFixed(2)}`;

// Preview swatches for the Visual style cards. Calm uses the muted ramp; Signature
// deliberately puts the brand bar next to destructive to show the clash it fixes.
interface VisualCardData {
    kind: VisualStyle;
    name: string;
    blurb: string;
    bars: string[];
}

const VISUAL_CARDS: VisualCardData[] = [
    {
        kind: 'calm',
        name: 'Calm',
        blurb: 'Upright headings, muted flat charts. The readable default.',
        bars: ['oklch(0.605 0.105 28)', 'oklch(0.715 0.085 70)', 'oklch(0.675 0.045 88)', 'oklch(0.565 0.018 250)'],
    },
    {
        kind: 'signature',
        name: 'Signature',
        blurb: "Italic serif headings, saturated charts. Today's look.",
        bars: ['var(--destructive)', 'var(--warning)', 'var(--brand)', 'color-mix(in oklch, var(--warning) 50%, var(--stat-icon))'],
    },
];
const VISUAL_BAR_HEIGHTS = [16, 11, 13, 8];

function VisualCard({
    card, selected, disabled, onSelect,
}: {
    card: VisualCardData;
    selected: boolean;
    disabled?: boolean;
    onSelect: () => void;
}) {
    const { kind, name, blurb, bars } = card;
    const calm = kind === 'calm';
    return (
        <button
            type="button"
            onClick={onSelect}
            disabled={disabled}
            aria-pressed={selected}
            className={cn(
                'flex flex-col overflow-hidden rounded-lg border bg-well text-left transition-colors',
                selected
                    ? 'border-brand/55 ring-1 ring-brand/40'
                    : 'border-card-border border-t-card-border-top hover:border-t-card-border-hover',
                disabled && 'opacity-50',
            )}
        >
            <div className="flex h-[74px] flex-col justify-center gap-1.5 border-b border-hairline px-3.5">
                <span
                    className={cn(
                        'text-[22px] leading-none text-stat-value',
                        calm ? 'font-sans font-semibold not-italic' : 'font-display font-normal italic',
                    )}
                >
                    Critical
                </span>
                <span className="flex items-end gap-1" style={{ height: 16 }}>
                    {bars.map((b, i) => (
                        <span
                            key={i}
                            className="block w-[9px] rounded-sm"
                            style={{ background: b, height: VISUAL_BAR_HEIGHTS[i] }}
                        />
                    ))}
                </span>
            </div>
            <div className="px-3.5 pb-3 pt-2.5">
                <div className="flex items-center gap-2 text-[13px] font-semibold text-stat-value">
                    {name}
                    {selected ? <Check className="h-3.5 w-3.5 text-brand" strokeWidth={2.5} /> : null}
                </div>
                <p className="mt-1 text-[11px] leading-snug text-stat-subtitle">{blurb}</p>
            </div>
        </button>
    );
}

export function AppearanceSection({
    quickLinkCandidates = [],
}: {
    quickLinkCandidates?: NavDestination[];
}) {
    const [density, setDensity] = useDensity();
    const [chipColorMode, setChipColorMode] = useLogChipColorMode();
    const [topNavLabels, setTopNavLabels] = useTopNavLabels();
    const [topNavAlign, setTopNavAlign] = useTopNavAlign();
    const [topNavMode, setTopNavMode] = useTopNavMode();
    const {
        persistedIds: quickLinkIds,
        addQuickLink,
        removeQuickLink,
        resetQuickLinks,
    } = useTopNavQuickLinks();
    const persistedSet = new Set(quickLinkIds);
    const unpinnedCandidates = quickLinkCandidates.filter((item) => !persistedSet.has(item.value));
    const atCapacity = quickLinkIds.length >= MAX_QUICK_LINKS;
    const addEnabled = !atCapacity && unpinnedCandidates.length > 0;
    const addDisabledReason = atCapacity
        ? 'Remove a pin or reset to free a slot'
        : 'No more destinations available on this node';
    const addOptions = unpinnedCandidates.map((item) => ({
        value: item.value,
        label: item.label,
    }));
    const {
        theme, accent, borderBoost, glow, contrast, uiFont, monoFont, typeScale,
        headingStyle, chartStyle, reducedEffects, reducedMotion, readability,
        setTheme, setAccent, setBorderBoost, setGlow, setContrast, setUiFont, setMonoFont, setTypeScale,
        setVisualStyle, setHeadingStyle, setChartStyle, setReducedEffects, setReducedMotion, setReadability,
    } = useTheme();
    const accentLabel = ACCENTS.find((a) => a.id === accent)?.label ?? 'Cyan';
    // Readability is a sticky master: it forces the calm resolution at apply time
    // without mutating the stored sub-axes, so the controls reflect the forced
    // value and lock while it is on. Effects are reduced under readability too.
    const effectiveReduced = readability || reducedEffects;
    const effectiveContrast = contrast + (readability ? 0.18 : 0);
    // A card is selected only while the stored sub-axes still match its preset, so
    // a custom combination de-selects both (and readability resolves to null).
    // Shared with the topbar quick-switch via activeVisualStyle so both surfaces
    // agree on which style is active.
    const activeVisual = activeVisualStyle({ headingStyle, chartStyle, reducedEffects, readability });

    return (
        <div className="flex flex-col gap-10">
            <SettingsSection title="Visual style" kicker="the master switch">
                <div className="grid grid-cols-2 gap-2.5 pt-3">
                    {VISUAL_CARDS.map((c) => (
                        <VisualCard
                            key={c.kind}
                            card={c}
                            selected={activeVisual === c.kind}
                            disabled={readability}
                            onSelect={() => setVisualStyle(c.kind)}
                        />
                    ))}
                </div>
                {readability ? (
                    <div className="mt-3 flex items-start gap-2.5 rounded-md border border-brand/30 bg-brand/10 px-3 py-2.5">
                        <Info className="mt-0.5 h-4 w-4 shrink-0 text-brand" strokeWidth={1.5} />
                        <p className="text-sm leading-relaxed text-stat-title">
                            <span className="font-medium text-brand">Readability mode is on.</span> It forces the calmest
                            settings and a small contrast lift. Turn it off below to choose a style by hand.
                        </p>
                    </div>
                ) : null}
            </SettingsSection>

            <SettingsSection title="Security visualization" kicker="the chart fix">
                <SettingsField
                    label="Chart palette"
                    helper="Muted desaturates the severity colors; Heat is one warm ramp with no red/blue clash; Signature is the saturated set."
                    align="start"
                >
                    <SegmentedControl
                        value={readability ? 'muted' : chartStyle}
                        options={CHART_STYLE_OPTIONS}
                        onChange={setChartStyle}
                        disabled={readability}
                        ariaLabel="Chart palette"
                    />
                </SettingsField>
            </SettingsSection>

            <SettingsSection title="Readability" kicker="this browser">
                <SettingsField
                    label="Readability mode"
                    helper="One switch: upright headings, muted flat charts, reduced effects, and a contrast lift."
                >
                    <TogglePill checked={readability} onChange={setReadability} aria-label="Readability mode" />
                </SettingsField>

                <SettingsField
                    label="Header style"
                    helper="Clean uses the upright interface face; Signature keeps the italic display serif."
                    align="start"
                >
                    <SegmentedControl
                        value={readability ? 'clean' : headingStyle}
                        options={HEADING_STYLE_OPTIONS}
                        onChange={setHeadingStyle}
                        disabled={readability}
                        ariaLabel="Header style"
                    />
                </SettingsField>

                <SettingsField
                    label="Contrast"
                    helper="Master contrast: spreads the page, ink, and borders together. Pair high contrast with OLED for the crispest panel."
                >
                    <div className="flex items-center gap-3">
                        <Slider
                            value={[contrast]}
                            min={CONTRAST.min}
                            max={CONTRAST.max}
                            step={CONTRAST.step}
                            onValueChange={([v]) => setContrast(v)}
                            aria-label="Contrast"
                        />
                        <span className="w-12 shrink-0 text-right font-mono text-xs tabular-nums text-stat-subtitle">
                            {fmtSigned(effectiveContrast)}
                        </span>
                    </div>
                </SettingsField>
            </SettingsSection>

            <SettingsSection title="Motion & effects" kicker="this browser">
                {!reducedMotion ? (
                    <SettingsCallout
                        tone="warn"
                        icon={<Info className="h-4 w-4" strokeWidth={1.5} />}
                        title="Constrained graphics"
                        subtitle="If the active Sencho tab feels heavy on integrated graphics or similar devices, turn on Reduced motion. Reduced effects and Calm alone may not be enough for that idle cost."
                    />
                ) : null}
                <SettingsField
                    label="Reduced motion"
                    helper="Minimizes interface animations and transitions (dialogs, menus, expand and collapse). Calm turns this on by default; choosing Signature turns it off. You can still toggle it independently afterward. First control to try for high idle GPU use on constrained graphics. Toasts are unaffected."
                >
                    <TogglePill
                        checked={reducedMotion}
                        onChange={setReducedMotion}
                        aria-label="Reduced motion"
                    />
                </SettingsField>

                <SettingsField
                    label="Reduced effects"
                    helper="Flattens card bevels, the accent glow, and chart gradients, and turns off glass blur with solid chrome fills. Also stops the decorative masthead rail animations even if Reduced motion is off. Optional secondary material simplification; not a substitute for Reduced motion on reported idle GPU cost."
                >
                    <TogglePill
                        checked={effectiveReduced}
                        onChange={setReducedEffects}
                        disabled={readability}
                        aria-label="Reduced effects"
                    />
                </SettingsField>

                <SettingsField
                    label="Ambient glow"
                    helper="Intensity of the accent-tinted glow behind the page."
                >
                    <div className="flex items-center gap-3">
                        <Slider
                            value={[glow]}
                            min={GLOW.min}
                            max={GLOW.max}
                            step={GLOW.step}
                            onValueChange={([v]) => setGlow(v)}
                            disabled={effectiveReduced}
                            aria-label="Ambient glow"
                        />
                        <span className="w-12 shrink-0 text-right font-mono text-xs tabular-nums text-stat-subtitle">
                            {glow.toFixed(2)}
                        </span>
                    </div>
                </SettingsField>

                <SettingsActions>
                    <SettingsSecondaryButton
                        onClick={() => setVisualStyle('calm')}
                        disabled={readability}
                    >
                        Reset to default
                    </SettingsSecondaryButton>
                </SettingsActions>
            </SettingsSection>

            <SettingsSection title="Theme" kicker="this browser">
                <div className="pt-3">
                    <ThemePreview />
                </div>

                <SettingsField
                    label="Mode"
                    helper="Dim lifts surfaces off black; OLED is true black; Light inverts; Auto follows your OS."
                >
                    <SegmentedControl
                        value={theme}
                        options={THEME_MODE_OPTIONS}
                        onChange={setTheme}
                        ariaLabel="Theme mode"
                    />
                </SettingsField>

                <SettingsField
                    label="Accent"
                    helper={`The one data color, used for charts, rails, and focus. Currently ${accentLabel}.`}
                    align="start"
                >
                    <AccentPicker value={accent} onChange={setAccent} />
                </SettingsField>

                <SettingsField
                    label="Border brightness"
                    helper="Lift or soften every hairline so separation reads exactly how you like it."
                >
                    <div className="flex items-center gap-3">
                        <Slider
                            value={[borderBoost]}
                            min={BORDER_BOOST.min}
                            max={BORDER_BOOST.max}
                            step={BORDER_BOOST.step}
                            onValueChange={([v]) => setBorderBoost(v)}
                            disabled={readability}
                            aria-label="Border brightness"
                        />
                        <span className="w-12 shrink-0 text-right font-mono text-xs tabular-nums text-stat-subtitle">
                            {fmtSigned(readability ? 0.03 : borderBoost)}
                        </span>
                    </div>
                </SettingsField>

                <SettingsActions>
                    <SettingsSecondaryButton
                        onClick={() => {
                            setContrast(CONTRAST.default);
                            setBorderBoost(BORDER_BOOST.default);
                            setGlow(GLOW.default);
                        }}
                    >
                        Reset fine-tune
                    </SettingsSecondaryButton>
                </SettingsActions>
            </SettingsSection>

            <SettingsSection title="Typography" kicker="this browser">
                <SettingsField
                    label="Interface font"
                    helper="The sans face for body, labels, navigation, and buttons. Heading style follows your Visual style choice."
                    align="start"
                >
                    <TypeChips value={uiFont} options={UI_FONT_OPTIONS} onChange={setUiFont} ariaLabel="Interface font" />
                </SettingsField>

                <SettingsField
                    label="Data font"
                    helper="The mono face for terminal, stats, codes, and timestamps."
                    align="start"
                >
                    <TypeChips value={monoFont} options={MONO_FONT_OPTIONS} onChange={setMonoFont} ariaLabel="Data font" />
                </SettingsField>

                <SettingsField
                    label="Text size"
                    helper="Scales the whole interface from a single root multiplier. Default 1.00×."
                >
                    <div className="flex items-center gap-3">
                        <Slider
                            value={[typeScale]}
                            min={TYPE_SCALE.min}
                            max={TYPE_SCALE.max}
                            step={TYPE_SCALE.step}
                            onValueChange={([v]) => setTypeScale(v)}
                            aria-label="Text size"
                        />
                        <span className="w-12 shrink-0 text-right font-mono text-xs tabular-nums text-stat-subtitle">
                            {typeScale.toFixed(2)}×
                        </span>
                    </div>
                </SettingsField>
            </SettingsSection>

            <SettingsSection title="Display" kicker="this browser">
                <SettingsField
                    label="Density"
                    helper={DENSITY_DESCRIPTIONS[density]}
                >
                    <Combobox
                        options={DENSITY_OPTIONS}
                        value={density}
                        onValueChange={(v) => {
                            if (v === 'comfortable' || v === 'compact') setDensity(v);
                        }}
                        placeholder="Select density"
                    />
                </SettingsField>

                <SettingsField
                    label="Log chip color"
                    helper="Applies to service chips on multi-service or multi-container stacks. Unified uses the accent color for all chips. Per-service assigns each service a stable label color for faster visual scanning."
                >
                    <SegmentedControl
                        value={chipColorMode}
                        options={CHIP_COLOR_OPTIONS}
                        onChange={setChipColorMode}
                        ariaLabel="Log chip color mode"
                    />
                </SettingsField>
            </SettingsSection>

            <SettingsSection title="Navigation" kicker="this browser">
                {topNavMode === 'classic' ? (
                    <SettingsCallout
                        tone="warn"
                        icon={<Info className="h-4 w-4" strokeWidth={1.5} />}
                        title="Classic bar retiring"
                        subtitle="Classic bar will be removed soon. Your preference is kept until then."
                    />
                ) : null}
                <SettingsField
                    label="Navigation style"
                    helper="Smart bar is the recommended default: primary destinations stay visible, and the rest live under More. Classic keeps the full horizontal strip. Compact launcher puts destinations in a menu with optional quick links."
                >
                    <SegmentedControl
                        value={topNavMode}
                        options={TOP_NAV_MODE_OPTIONS}
                        onChange={setTopNavMode}
                        ariaLabel="Navigation style"
                    />
                </SettingsField>

                {(topNavMode === 'classic' || topNavMode === 'smart') && (
                    <SettingsField
                        label="Top navigation labels"
                        helper="Show text labels beside top navigation icons. Turn off for a more compact navigation bar."
                    >
                        <TogglePill checked={topNavLabels} onChange={setTopNavLabels} />
                    </SettingsField>
                )}

                {(topNavMode === 'classic' || topNavMode === 'smart') && !topNavLabels && (
                    <SettingsField
                        label="Top navigation alignment"
                        helper="Place the icon-only navigation against the left edge or centered in the bar."
                    >
                        <SegmentedControl
                            value={topNavAlign}
                            options={TOP_NAV_ALIGN_OPTIONS}
                            onChange={setTopNavAlign}
                            ariaLabel="Top navigation alignment"
                        />
                    </SettingsField>
                )}

                {topNavMode === 'compact' && (
                    <SettingsField
                        label="Quick links"
                        helper="Up to seven pinned destinations on the top bar. Defaults are a starting set; add reachable destinations here or with the trailing + on the Compact bar."
                    >
                        <div className="flex w-full flex-col gap-2">
                            {quickLinkIds.length === 0 ? (
                                <p className="font-mono text-[11px] text-stat-subtitle">No quick links pinned.</p>
                            ) : (
                                <ul className="flex flex-col gap-1">
                                    {quickLinkIds.map((id) => {
                                        const item = getAppNavItem(id);
                                        const label = item?.label ?? id;
                                        return (
                                            <li
                                                key={id}
                                                className="flex items-center justify-between gap-2 rounded-md border border-glass-border px-2 py-1.5"
                                            >
                                                <span className="font-mono text-[11px] uppercase tracking-[0.14em]">
                                                    {label}
                                                </span>
                                                <SettingsSecondaryButton
                                                    type="button"
                                                    aria-label={`Remove ${label}`}
                                                    onClick={() => removeQuickLink(id)}
                                                >
                                                    Remove
                                                </SettingsSecondaryButton>
                                            </li>
                                        );
                                    })}
                                </ul>
                            )}
                            <div className="flex flex-col gap-1.5">
                                <span className="font-mono text-[10px] uppercase tracking-[0.18em] text-stat-subtitle">
                                    Add quick link
                                </span>
                                {addEnabled ? (
                                    <Combobox
                                        options={addOptions}
                                        value=""
                                        onValueChange={(value) => {
                                            if (value) addQuickLink(value as ActiveView);
                                        }}
                                        placeholder="Choose a destination"
                                    />
                                ) : (
                                    <p className="font-mono text-[11px] text-stat-subtitle">{addDisabledReason}</p>
                                )}
                            </div>
                            <SettingsActions>
                                <SettingsSecondaryButton type="button" onClick={resetQuickLinks}>
                                    Reset to defaults
                                </SettingsSecondaryButton>
                            </SettingsActions>
                        </div>
                    </SettingsField>
                )}
            </SettingsSection>

            <p className="font-mono text-[10px] leading-3 uppercase tracking-[0.18em] text-stat-subtitle/70">
                ⓘ saved to this browser only · every device remembers its own choice
            </p>
        </div>
    );
}
