import { Head, router } from '@inertiajs/react';
import { useEffect, useMemo, useState } from 'react';
import { GrowBetterConfig } from '@/components/grow-better/config-panel';
import { GrowBetterHelpProvider } from '@/components/grow-better/help-tip';
import { GrowBetterHero } from '@/components/grow-better/hero';
import { GrowBetterPillars } from '@/components/grow-better/pillar-grid';
import { GrowBetterTrajectory } from '@/components/grow-better/trajectory';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { assess, formatValue, normalizeWeights } from '@/lib/grow-better-score';
import { clients } from '@/routes/grow-better';
import { show, update } from '@/routes/grow-better/clients';
import type {
    GrowBetterCompany,
    GrowBetterDraft,
    GrowBetterHelp,
    GrowBetterModel,
    GrowBetterPreset,
    GrowBetterTrendPoint,
} from '@/types/grow-better';

type Props = {
    client: GrowBetterCompany;
    companies: GrowBetterCompany[];
    period: string;
    delta_label: string;
    industry: string;
    narrative: string;
    currency: string;
    presets: Record<string, GrowBetterPreset>;
    score_help: GrowBetterHelp;
    fix_help: GrowBetterHelp;
    model: GrowBetterModel;
    prior_pillar_scores: Record<string, number | null>;
    prior_overall: number | null;
    trend: GrowBetterTrendPoint[];
    history_pending: boolean;
    backend_configured: boolean;
    report_available: boolean;
};

const periods = [
    { value: 'month', label: 'This Month' },
    { value: 'quarter', label: 'This Quarter' },
    { value: 'year', label: 'This Year' },
];

function draftFrom(model: GrowBetterModel, industry: string): GrowBetterDraft {
    const enabled: Record<string, boolean> = {};
    const values: Record<string, number | null> = {};

    for (const pillar of model.pillars) {
        for (const kpi of pillar.kpis) {
            enabled[kpi.key] = kpi.enabled;
            values[kpi.key] = kpi.source === 'manual' ? kpi.value : null;
        }
    }

    return {
        industry,
        weights: { ...model.weights },
        enabled,
        values,
    };
}

function overlay(
    model: GrowBetterModel,
    draft: GrowBetterDraft,
    currency: string,
): GrowBetterModel {
    return {
        weights: draft.weights,
        pillars: model.pillars.map((pillar) => ({
            ...pillar,
            kpis: pillar.kpis.map((kpi) => {
                const enabled = draft.enabled[kpi.key] ?? kpi.enabled;

                if (kpi.source !== 'manual') {
                    return { ...kpi, enabled };
                }

                const value = draft.values[kpi.key] ?? null;

                return {
                    ...kpi,
                    enabled,
                    value,
                    display: formatValue(value, kpi.unit, currency),
                };
            }),
        })),
    };
}

export default function GrowBetterShow(props: Props) {
    const [draft, setDraft] = useState(() =>
        draftFrom(props.model, props.industry),
    );
    const [saving, setSaving] = useState(false);
    const serverDraft = useMemo(
        () => draftFrom(props.model, props.industry),
        [props.model, props.industry],
    );
    const model = useMemo(
        () => overlay(props.model, draft, props.currency),
        [props.model, draft, props.currency],
    );
    const assessment = useMemo(
        () => assess(model, props.prior_pillar_scores, props.prior_overall),
        [model, props.prior_pillar_scores, props.prior_overall],
    );
    const draftSignature = JSON.stringify(draft);
    const serverSignature = JSON.stringify(serverDraft);

    useEffect(() => {
        if (draftSignature === serverSignature) {
            return;
        }

        const timer = window.setTimeout(() => {
            setSaving(true);
            router.put(
                update.url(props.client.id),
                {
                    account_type: props.client.account_type,
                    industry: draft.industry,
                    weights: draft.weights,
                    kpis: Object.fromEntries(
                        Object.keys(draft.enabled).map((key) => [
                            key,
                            {
                                enabled: draft.enabled[key],
                                value: draft.values[key],
                            },
                        ]),
                    ),
                },
                {
                    preserveScroll: true,
                    preserveState: true,
                    onFinish: () => setSaving(false),
                },
            );
        }, 500);

        return () => window.clearTimeout(timer);
    }, [draft, draftSignature, props.client, serverSignature]);

    function visit(next: {
        id?: string;
        accountType?: string;
        period?: string;
    }) {
        router.get(
            show.url(next.id ?? props.client.id, {
                query: {
                    account_type: next.accountType ?? props.client.account_type,
                    period: next.period ?? props.period,
                },
            }),
        );
    }

    function applyPreset(industry: string) {
        const preset = props.presets[industry];

        if (!preset) {
            return;
        }

        setDraft((current) => ({
            ...current,
            industry,
            weights: { ...preset.weights },
            enabled: { ...preset.enabled },
        }));
    }

    const narrative =
        props.presets[draft.industry]?.narrative ?? props.narrative;

    return (
        <>
            <Head title={`${props.client.name} · Grow Better`} />
            <GrowBetterHelpProvider>
                <div className="mx-auto flex w-full max-w-6xl flex-col gap-10 p-4 pb-16">
                    <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
                        <div>
                            <p className="text-[11px] font-semibold tracking-widest text-primary uppercase">
                                Grow Better
                            </p>
                            <h1 className="text-2xl font-semibold tracking-tight">
                                {props.client.name}
                            </h1>
                        </div>
                        <div className="flex flex-wrap items-center gap-2">
                            <div className="rounded-full border px-3 py-1.5 text-sm tabular-nums">
                                <span className="font-semibold">
                                    {assessment.overall}
                                </span>
                                <span className="text-muted-foreground">
                                    {' '}
                                    / 1000
                                </span>
                            </div>
                            <Select
                                value={`${props.client.account_type}:${props.client.id}`}
                                onValueChange={(value) => {
                                    const separator = value.indexOf(':');
                                    visit({
                                        accountType: value.slice(0, separator),
                                        id: value.slice(separator + 1),
                                    });
                                }}
                            >
                                <SelectTrigger
                                    className="w-52"
                                    aria-label="Client"
                                >
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {props.companies.map((company) => (
                                        <SelectItem
                                            key={`${company.account_type}:${company.id}`}
                                            value={`${company.account_type}:${company.id}`}
                                        >
                                            {company.name}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <Select
                                value={draft.industry}
                                onValueChange={applyPreset}
                            >
                                <SelectTrigger
                                    className="w-48"
                                    aria-label="Industry"
                                >
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {Object.entries(props.presets).map(
                                        ([key, preset]) => (
                                            <SelectItem key={key} value={key}>
                                                {preset.label}
                                            </SelectItem>
                                        ),
                                    )}
                                </SelectContent>
                            </Select>
                            <Select
                                value={props.period}
                                onValueChange={(period) => visit({ period })}
                            >
                                <SelectTrigger
                                    className="w-40"
                                    aria-label="Period"
                                >
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {periods.map((period) => (
                                        <SelectItem
                                            key={period.value}
                                            value={period.value}
                                        >
                                            {period.label}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    </div>

                    {!props.backend_configured && (
                        <Alert>
                            <AlertTitle>
                                Backend API is not configured
                            </AlertTitle>
                            <AlertDescription>
                                Book KPIs stay empty until the Monily backend is
                                connected. You can still enter manual values.
                            </AlertDescription>
                        </Alert>
                    )}
                    {props.backend_configured && !props.report_available && (
                        <Alert>
                            <AlertTitle>No books for this period</AlertTitle>
                            <AlertDescription>
                                Calculated KPIs are left out of the score until
                                a report is available. Manual values still
                                count.
                            </AlertDescription>
                        </Alert>
                    )}

                    <GrowBetterHero
                        assessment={assessment}
                        narrative={narrative}
                        deltaLabel={props.delta_label}
                        scoreHelp={props.score_help}
                    />

                    <section className="space-y-4">
                        <div className="flex items-end justify-between gap-4">
                            <div>
                                <p className="text-[11px] font-semibold tracking-widest text-muted-foreground uppercase">
                                    The pillars
                                </p>
                                <h2 className="text-xl font-semibold tracking-tight">
                                    What drives your score
                                </h2>
                                <p className="mt-1 max-w-xl text-sm text-muted-foreground">
                                    Core pillars start equal, then follow the
                                    weights you set. Empty KPIs stay out of the
                                    score until they have a number.
                                </p>
                            </div>
                            <a
                                href="#grow-better-config"
                                className="text-sm font-medium text-primary"
                            >
                                Customize
                            </a>
                        </div>
                        <GrowBetterPillars
                            pillars={assessment.pillars}
                            onEnable={(key, enabled) =>
                                setDraft((current) => ({
                                    ...current,
                                    weights: {
                                        ...current.weights,
                                        [key]: enabled ? 15 : 0,
                                    },
                                }))
                            }
                        />
                    </section>

                    <section id="grow-better-config" className="space-y-4">
                        <div>
                            <p className="text-[11px] font-semibold tracking-widest text-muted-foreground uppercase">
                                Configure
                            </p>
                            <h2 className="text-xl font-semibold tracking-tight">
                                Set your weights and KPIs
                            </h2>
                            <p className="mt-1 max-w-xl text-sm text-muted-foreground">
                                Drag a slider to reweight. The score updates
                                immediately. Type any KPI the books do not
                                calculate.
                            </p>
                        </div>
                        <GrowBetterConfig
                            model={model}
                            weights={draft.weights}
                            enabled={draft.enabled}
                            values={draft.values}
                            saving={saving}
                            onWeight={(key, weight) =>
                                setDraft((current) => ({
                                    ...current,
                                    weights: {
                                        ...current.weights,
                                        [key]: weight,
                                    },
                                }))
                            }
                            onToggle={(key, enabled) =>
                                setDraft((current) => ({
                                    ...current,
                                    enabled: {
                                        ...current.enabled,
                                        [key]: enabled,
                                    },
                                }))
                            }
                            onValue={(key, value) =>
                                setDraft((current) => ({
                                    ...current,
                                    values: { ...current.values, [key]: value },
                                }))
                            }
                            onBalance={() =>
                                setDraft((current) => ({
                                    ...current,
                                    weights: normalizeWeights(current.weights),
                                }))
                            }
                            onReset={() => applyPreset(draft.industry)}
                        />
                    </section>

                    <section className="space-y-4">
                        <p className="text-[11px] font-semibold tracking-widest text-muted-foreground uppercase">
                            Trajectory and priorities
                        </p>
                        <GrowBetterTrajectory
                            assessment={assessment}
                            trend={props.trend}
                            historyPending={props.history_pending}
                            fixHelp={props.fix_help}
                        />
                    </section>
                </div>
            </GrowBetterHelpProvider>
        </>
    );
}

GrowBetterShow.layout = {
    breadcrumbs: [
        {
            title: 'Grow Better',
            href: clients(),
        },
        {
            title: 'Client',
            href: clients(),
        },
    ],
};
