import { useEffect, useState } from "react";
import {
    AreaChart,
    BarChart3,
    LineChart,
    Search,
    X,
} from "lucide-react";

import type {
    WorkspaceChartMode,
    WorkspaceChartTimeRange,
    WorkspaceChartInterval,
} from "../../../components/charts/WorkspaceChart";
import type { ChartVariable } from "../../telemetry/types/telemetryCatalog";

export type ChartConfigModalChart = {
    id: string;
    title: string;
    mode: WorkspaceChartMode;
    selectedSensorKeys: string[];
    hiddenSensorKeys?: string[];
    timeRange: WorkspaceChartTimeRange;
    interval: WorkspaceChartInterval;
};

type ChartConfigModalProps = {
    theme: "dark" | "light";
    chart: ChartConfigModalChart;
    variables: ChartVariable[];
    maxVariables?: number;
    onClose?: () => void;
    onSave: (chart: ChartConfigModalChart) => void;
};

const RADIUS = "rounded-[6px]";

export function ChartConfigModal({
    theme,
    chart,
    variables,
    maxVariables = 6,
    onClose,
    onSave,
}: ChartConfigModalProps) {
    const isDark = theme === "dark";
    const [search, setSearch] = useState("");
    const [draft, setDraft] = useState<ChartConfigModalChart>(chart);

    useEffect(() => {
        setDraft(chart);
    }, [chart.id]);

    const filteredVariables = variables.filter((variable) =>
        `${variable.label} ${variable.category} ${variable.group} ${variable.unit}`
            .toLowerCase()
            .includes(search.toLowerCase()),
    );

    const toggleVariable = (key: string) => {
        setDraft((current) => {
            const alreadySelected = current.selectedSensorKeys.includes(key);

            if (!alreadySelected && current.selectedSensorKeys.length >= maxVariables) {
                return current;
            }

            const selectedSensorKeys = alreadySelected
                ? current.selectedSensorKeys.filter((item) => item !== key)
                : [...current.selectedSensorKeys, key];

            return {
                ...current,
                selectedSensorKeys,
                hiddenSensorKeys: (current.hiddenSensorKeys ?? []).filter(
                    (item) => item !== key,
                ),
            };
        });
    };

    const discardAndClose = () => {
        onClose?.();
    };

    const saveAndClose = () => {
        onSave(draft);
    };

    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/55 p-6">
            <div
                className={
                    isDark
                        ? `${RADIUS} w-full max-w-[760px] border border-[#263247] bg-[#0E1726] shadow-2xl`
                        : `${RADIUS} w-full max-w-[760px] border border-[#D7DEE8] bg-white shadow-2xl`
                }
            >
                <header
                    className={
                        isDark
                            ? "flex items-center justify-between border-b border-[#263247] px-6 py-5"
                            : "flex items-center justify-between border-b border-[#D7DEE8] px-6 py-5"
                    }
                >
                    <div>
                        <p
                            className={
                                isDark
                                    ? "text-xs font-black uppercase tracking-[0.2em] text-[#4FD1C5]"
                                    : "text-xs font-black uppercase tracking-[0.2em] text-[#0F766E]"
                            }
                        >
                            Configuração do gráfico
                        </p>

                        <h2 className="mt-1 text-xl font-black">{draft.title}</h2>
                    </div>

                    <button
                        type="button"
                        onClick={discardAndClose}
                        className={
                            isDark
                                ? `${RADIUS} p-2 text-[#A8B3C7] transition hover:bg-[#111A2B] hover:text-white`
                                : `${RADIUS} p-2 text-slate-500 transition hover:bg-[#F8FAFC] hover:text-[#0F172A]`
                        }
                    >
                        <X className="h-5 w-5" />
                    </button>
                </header>

                <main className="grid gap-6 p-6 md:grid-cols-[260px_minmax(0,1fr)]">
                    <section className="space-y-4">
                        <div>
                            <label className="mb-2 block text-sm font-black">Nome</label>
                            <input
                                value={draft.title}
                                onChange={(event) =>
                                    setDraft((current) => ({
                                        ...current,
                                        title: event.target.value,
                                    }))
                                }
                                className={
                                    isDark
                                        ? `${RADIUS} h-11 w-full border border-[#263247] bg-[#07101B] px-3 text-sm font-bold text-white outline-none`
                                        : `${RADIUS} h-11 w-full border border-[#D7DEE8] bg-[#F8FAFC] px-3 text-sm font-bold text-[#0F172A] outline-none`
                                }
                            />
                        </div>

                        <div>
                            <label className="mb-2 block text-sm font-black">
                                Tipo de gráfico
                            </label>

                            <div className="grid grid-cols-3 gap-2">
                                <ModeButton
                                    theme={theme}
                                    active={draft.mode === "line"}
                                    icon={<LineChart className="h-4 w-4" />}
                                    label="Linha"
                                    onClick={() =>
                                        setDraft((current) => ({
                                            ...current,
                                            mode: "line",
                                        }))
                                    }
                                />
                                <ModeButton
                                    theme={theme}
                                    active={draft.mode === "area"}
                                    icon={<AreaChart className="h-4 w-4" />}
                                    label="Área"
                                    onClick={() =>
                                        setDraft((current) => ({
                                            ...current,
                                            mode: "area",
                                        }))
                                    }
                                />
                                <ModeButton
                                    theme={theme}
                                    active={draft.mode === "bar"}
                                    icon={<BarChart3 className="h-4 w-4" />}
                                    label="Barras"
                                    onClick={() =>
                                        setDraft((current) => ({
                                            ...current,
                                            mode: "bar",
                                        }))
                                    }
                                />
                            </div>
                        </div>

                        <div
                            className={
                                isDark
                                    ? `${RADIUS} border border-[#263247] bg-[#111A2B] p-3`
                                    : `${RADIUS} border border-[#D7DEE8] bg-[#F8FAFC] p-3`
                            }
                        >
                            <p className="text-xs font-black uppercase tracking-[0.18em] text-[#7F8CA3]">
                                Selecionadas
                            </p>

                            <p className="mt-2 text-sm font-black">
                                {draft.selectedSensorKeys.length}/{maxVariables}
                            </p>
                        </div>
                    </section>

                    <section>
                        <div
                            className={
                                isDark
                                    ? `${RADIUS} mb-4 flex h-10 items-center gap-2 border border-[#263247] bg-[#07101B] px-3 text-sm text-[#7F8CA3]`
                                    : `${RADIUS} mb-4 flex h-10 items-center gap-2 border border-[#D7DEE8] bg-[#F8FAFC] px-3 text-sm text-slate-500`
                            }
                        >
                            <Search className="h-4 w-4" />

                            <input
                                value={search}
                                onChange={(event) => setSearch(event.target.value)}
                                placeholder="Pesquisar variável..."
                                className="w-full bg-transparent outline-none placeholder:text-inherit"
                            />
                        </div>

                        <div className="custom-scrollbar max-h-[340px] space-y-2 overflow-y-auto pr-1">
                            {filteredVariables.map((variable, index) => {
                                const active = draft.selectedSensorKeys.includes(
                                    variable.key,
                                );

                                return (
                                    <VariableRow
                                        key={variable.key}
                                        theme={theme}
                                        variable={variable}
                                        color={getVariableColor(index)}
                                        active={active}
                                        disabled={
                                            !active &&
                                            draft.selectedSensorKeys.length >= maxVariables
                                        }
                                        onClick={() => toggleVariable(variable.key)}
                                    />
                                );
                            })}

                            {filteredVariables.length === 0 && (
                                <EmptyVariableList theme={theme} />
                            )}
                        </div>
                    </section>
                </main>

                <footer
                    className={
                        isDark
                            ? "flex justify-end gap-3 border-t border-[#263247] px-6 py-5"
                            : "flex justify-end gap-3 border-t border-[#D7DEE8] px-6 py-5"
                    }
                >
                    <button
                        type="button"
                        onClick={saveAndClose}
                        className={
                            isDark
                                ? `${RADIUS} border border-[#263247] bg-[#111A2B] px-5 py-2.5 text-sm font-bold text-white`
                                : `${RADIUS} border border-[#D7DEE8] bg-[#F8FAFC] px-5 py-2.5 text-sm font-bold text-[#0F172A]`
                        }
                    >
                        Guardar
                    </button>
                </footer>
            </div>
        </div>
    );
}

function VariableRow({
    theme,
    variable,
    color,
    active,
    disabled,
    onClick,
}: {
    theme: "dark" | "light";
    variable: ChartVariable;
    color: string;
    active: boolean;
    disabled: boolean;
    onClick: () => void;
}) {
    const isDark = theme === "dark";

    return (
        <button
            type="button"
            disabled={disabled}
            onClick={onClick}
            className={
                active
                    ? isDark
                        ? `${RADIUS} flex h-12 w-full items-center justify-between border border-[#36506D] bg-[#132033] px-3 text-left text-sm font-bold text-white`
                        : `${RADIUS} flex h-12 w-full items-center justify-between border border-[#0F766E]/30 bg-[#ECFDF5] px-3 text-left text-sm font-bold text-[#0F172A]`
                    : disabled
                        ? isDark
                            ? `${RADIUS} flex h-12 w-full cursor-not-allowed items-center justify-between border border-[#263247] bg-[#111A2B]/50 px-3 text-left text-sm font-semibold text-[#7F8CA3]/50`
                            : `${RADIUS} flex h-12 w-full cursor-not-allowed items-center justify-between border border-[#D7DEE8] bg-[#F8FAFC]/60 px-3 text-left text-sm font-semibold text-slate-400`
                        : isDark
                            ? `${RADIUS} flex h-12 w-full items-center justify-between border border-[#263247] bg-[#111A2B] px-3 text-left text-sm font-semibold text-white transition hover:border-[#36506D]`
                            : `${RADIUS} flex h-12 w-full items-center justify-between border border-[#D7DEE8] bg-[#F8FAFC] px-3 text-left text-sm font-semibold text-[#0F172A] transition hover:bg-white`
            }
        >
            <span className="flex min-w-0 items-center gap-2">
                <span
                    className="h-3 w-3 shrink-0 rounded-full"
                    style={{ backgroundColor: color }}
                />

                <span className="min-w-0">
                    <span className="block truncate">{variable.label}</span>
                    <span
                        className={
                            isDark
                                ? "mt-0.5 block truncate text-xs font-bold text-[#7F8CA3]"
                                : "mt-0.5 block truncate text-xs font-bold text-slate-500"
                        }
                    >
                        {variable.group} · {variable.category}
                        {variable.unit ? ` · ${variable.unit}` : ""}
                    </span>
                </span>
            </span>

            <span
                className={
                    active
                        ? "text-xs font-black text-[#4FD1C5]"
                        : "text-xs font-bold text-[#7F8CA3]"
                }
            >
                {active ? "ON" : "OFF"}
            </span>
        </button>
    );
}

function EmptyVariableList({ theme }: { theme: "dark" | "light" }) {
    const isDark = theme === "dark";

    return (
        <div
            className={
                isDark
                    ? `${RADIUS} border border-dashed border-[#263247] px-4 py-6 text-center text-sm font-bold text-[#7F8CA3]`
                    : `${RADIUS} border border-dashed border-[#D7DEE8] px-4 py-6 text-center text-sm font-bold text-slate-500`
            }
        >
            Nenhuma variável encontrada.
        </div>
    );
}

function ModeButton({
    theme,
    active,
    icon,
    label,
    onClick,
}: {
    theme: "dark" | "light";
    active: boolean;
    icon?: React.ReactNode;
    label: string;
    onClick: () => void;
}) {
    return (
        <button
            type="button"
            onClick={onClick}
            className={
                active
                    ? theme === "dark"
                        ? `${RADIUS} flex items-center justify-center gap-2 bg-[#4FD1C5] px-3 py-2 text-xs font-black text-[#07101B]`
                        : `${RADIUS} flex items-center justify-center gap-2 bg-[#0F766E] px-3 py-2 text-xs font-black text-white`
                    : theme === "dark"
                        ? `${RADIUS} flex items-center justify-center gap-2 border border-[#263247] bg-[#111A2B] px-3 py-2 text-xs font-bold text-[#A8B3C7]`
                        : `${RADIUS} flex items-center justify-center gap-2 border border-[#D7DEE8] bg-[#F8FAFC] px-3 py-2 text-xs font-bold text-slate-600`
            }
        >
            {icon}
            {label}
        </button>
    );
}

function getVariableColor(index: number) {
    const colors = [
        "#4FD1C5",
        "#3B82F6",
        "#FACC15",
        "#7DD3FC",
        "#A5B4FC",
        "#FB7185",
    ];

    return colors[index % colors.length];
}