import { useState, useCallback } from "react";
import AppLayout from "@/Layouts/AppLayout";
import { Head, Link, router } from "@inertiajs/react";
import {
    FolderKanban,
    ChevronDown,
    ChevronRight,
    LayoutDashboard,
    LayoutTemplate,
    Settings2,
    GripVertical,
    BarChart3,
    Target,
    Globe,
    Users,
} from "lucide-react";
import PageHeader from "@/Components/PageHeader";
import { toast } from "sonner";
import {
    DndContext,
    closestCenter,
    PointerSensor,
    useSensor,
    useSensors,
} from "@dnd-kit/core";
import {
    SortableContext,
    verticalListSortingStrategy,
    rectSortingStrategy,
    useSortable,
    arrayMove,
} from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";
import { Button } from "@/Components/ui/button";
import { Badge } from "@/Components/ui/badge";
import { Switch } from "@/Components/ui/switch";
import {
    Card,
    CardContent,
    CardHeader,
    CardTitle,
    CardDescription,
} from "@/Components/ui/card";
import { Separator } from "@/Components/ui/separator";
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/Components/ui/select";

import { PROVIDER_ICON } from "@/Components/Dashboard/integrationIcons";
import MagicWandButton from "@/Components/Dashboard/MagicWandButton";

const TREND_MODE_OPTIONS = [
    { value: "on", label: "Ligado" },
    { value: "off", label: "Desligado" },
];

/* ── Linha arrastavel (KPI metric) ───────────────────────────── */
function SortableMetricRow({ metric, onToggle, saving }) {
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: metric.key });

    return (
        <div
            ref={setNodeRef}
            style={{
                transform: CSS.Transform.toString(transform),
                transition,
            }}
            className={[
                "flex items-center gap-2 py-1.5 px-1 rounded-md select-none",
                isDragging
                    ? "z-50 shadow-md bg-card opacity-90 ring-1 ring-border"
                    : "hover:bg-muted/40",
            ].join(" ")}
        >
            <button
                {...attributes}
                {...listeners}
                className="cursor-grab active:cursor-grabbing text-muted-foreground/50 hover:text-muted-foreground transition-colors shrink-0 touch-none"
                tabIndex={-1}
                aria-label="Arrastar para reordenar"
            >
                <GripVertical className="h-4 w-4" />
            </button>

            <span
                className={[
                    "flex-1 text-sm leading-none",
                    metric.visible ? "text-foreground" : "text-muted-foreground",
                ].join(" ")}
            >
                {metric.label}
            </span>

            {metric.calculated && (
                <span className="text-[10px] font-medium text-muted-foreground/60 shrink-0">
                    calc
                </span>
            )}

            <Switch
                checked={metric.visible}
                onCheckedChange={(v) => onToggle(metric.key, v)}
                disabled={saving}
                aria-label={`${metric.visible ? "Ocultar" : "Mostrar"} ${metric.label}`}
                className="shrink-0"
            />
        </div>
    );
}

/* ── Linha arrastavel de bloco ────────────────────────────────── */
function SortableBlockRow({ block, onToggle, saving, children }) {
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id: block.key });
    const [expanded, setExpanded] = useState(false);
    const hasChildren = !!children;

    return (
        <div
            ref={setNodeRef}
            style={{
                transform: CSS.Transform.toString(transform),
                transition,
            }}
            className={
                isDragging
                    ? "z-50 shadow-md bg-card opacity-90 ring-1 ring-border rounded-md"
                    : ""
            }
        >
            <div className="flex items-center gap-2 py-2 px-1 rounded-md hover:bg-muted/40">
                <button
                    {...attributes}
                    {...listeners}
                    className="cursor-grab active:cursor-grabbing text-muted-foreground/50 hover:text-muted-foreground transition-colors shrink-0 touch-none"
                    tabIndex={-1}
                    aria-label="Arrastar para reordenar"
                >
                    <GripVertical className="h-4 w-4" />
                </button>

                {hasChildren && (
                    <button
                        onClick={() => setExpanded(!expanded)}
                        className="text-muted-foreground/60 hover:text-muted-foreground transition-colors shrink-0"
                        aria-label={expanded ? "Recolher" : "Expandir"}
                    >
                        {expanded ? (
                            <ChevronDown className="h-4 w-4" />
                        ) : (
                            <ChevronRight className="h-4 w-4" />
                        )}
                    </button>
                )}

                <span
                    className={[
                        "flex-1 text-sm leading-none",
                        block.visible ? "text-foreground" : "text-muted-foreground",
                    ].join(" ")}
                >
                    {block.label}
                </span>

                <Switch
                    checked={block.visible}
                    onCheckedChange={(v) => onToggle(block.key, v)}
                    disabled={saving}
                    aria-label={`${block.visible ? "Ocultar" : "Mostrar"} ${block.label}`}
                    className="shrink-0"
                />
            </div>

            {hasChildren && expanded && (
                <div className="ml-6 border-l border-border/50 pl-2">
                    {children}
                </div>
            )}
        </div>
    );
}

/* ── Card arrastavel generico (integracao / aba) ─────────────── */
function SortableCard({ id, children }) {
    const {
        attributes,
        listeners,
        setNodeRef,
        transform,
        transition,
        isDragging,
    } = useSortable({ id });

    return (
        <div
            ref={setNodeRef}
            style={{
                transform: CSS.Transform.toString(transform),
                transition,
            }}
            className={
                isDragging
                    ? "z-50 scale-[1.03] opacity-85 [&>*]:shadow-xl [&>*]:ring-2 [&>*]:ring-primary/25"
                    : "transition-transform duration-200"
            }
        >
            {children({ dragHandleProps: { ...attributes, ...listeners } })}
        </div>
    );
}

/* ── Card de uma integracao ────────────────────────────────────── */
function IntegrationConfigCard({
    project,
    integrationType,
    integrationLabel,
    initialMetrics,
    initialBlocks,
    initialSectionVisible = false,
    dragHandleProps,
}) {
    const [metrics, setMetrics] = useState(initialMetrics);
    const [blocks, setBlocks] = useState(initialBlocks);
    const [sectionVisible, setSectionVisible] = useState(initialSectionVisible);
    const [saving, setSaving] = useState(false);

    const visibleMetricCount = metrics.filter((m) => m.visible).length;
    const ProviderIcon = PROVIDER_ICON[integrationType] ?? null;

    const metricSensors = useSensors(
        useSensor(PointerSensor, { activationConstraint: { distance: 5 } })
    );

    const blockSensors = useSensors(
        useSensor(PointerSensor, { activationConstraint: { distance: 6 } })
    );

    const persist = useCallback(
        (updatedMetrics, updatedBlocks, updatedSectionVisible) => {
            setSaving(true);
            router.put(
                route("projetos.dashboard-config.update", [
                    project.id,
                    integrationType,
                ]),
                {
                    metrics: updatedMetrics,
                    blocks: updatedBlocks,
                    section_visible: updatedSectionVisible,
                },
                {
                    preserveScroll: true,
                    onSuccess: () => {
                        toast.success("Configuracao salva.");
                        setSaving(false);
                    },
                    onError: () => {
                        toast.error("Erro ao salvar.");
                        setSaving(false);
                    },
                }
            );
        },
        [project.id, integrationType]
    );

    const handleMetricDragEnd = useCallback(
        ({ active, over }) => {
            if (!over || active.id === over.id) return;
            const oldIndex = metrics.findIndex((m) => m.key === active.id);
            const newIndex = metrics.findIndex((m) => m.key === over.id);
            const reordered = arrayMove(metrics, oldIndex, newIndex).map(
                (m, i) => ({ ...m, order: i })
            );
            setMetrics(reordered);
            persist(reordered, blocks, sectionVisible);
        },
        [metrics, blocks, sectionVisible, persist]
    );

    const handleBlockDragEnd = useCallback(
        ({ active, over }) => {
            if (!over || active.id === over.id) return;
            const oldIndex = blocks.findIndex((b) => b.key === active.id);
            const newIndex = blocks.findIndex((b) => b.key === over.id);
            const reordered = arrayMove(blocks, oldIndex, newIndex).map(
                (b, i) => ({ ...b, order: i })
            );
            setBlocks(reordered);
            persist(metrics, reordered, sectionVisible);
        },
        [blocks, metrics, sectionVisible, persist]
    );

    const handleMetricToggle = useCallback(
        (key, checked) => {
            const updated = metrics.map((m) =>
                m.key === key ? { ...m, visible: checked } : m
            );
            setMetrics(updated);
            persist(updated, blocks, sectionVisible);
        },
        [metrics, blocks, sectionVisible, persist]
    );

    const handleBlockToggle = useCallback(
        (key, checked) => {
            const updated = blocks.map((b) =>
                b.key === key ? { ...b, visible: checked } : b
            );
            setBlocks(updated);
            persist(metrics, updated, sectionVisible);
        },
        [metrics, blocks, sectionVisible, persist]
    );

    const handleSectionVisibleToggle = useCallback(
        (checked) => {
            setSectionVisible(checked);
            persist(metrics, blocks, checked);
        },
        [metrics, blocks, persist]
    );

    return (
        <Card className="flex flex-col">
            <CardHeader className="pb-3">
                <div className="flex items-start justify-between gap-2">
                    <CardTitle className="flex items-center gap-2 text-sm font-semibold leading-tight">
                        {dragHandleProps && (
                            <button
                                {...dragHandleProps}
                                className="cursor-grab active:cursor-grabbing text-muted-foreground/50 hover:text-muted-foreground transition-colors shrink-0 touch-none"
                                tabIndex={-1}
                                aria-label="Arrastar para reordenar integracao"
                            >
                                <GripVertical className="h-4 w-4" />
                            </button>
                        )}
                        {ProviderIcon && <ProviderIcon size={16} />}
                        {integrationLabel}
                    </CardTitle>
                    <Badge variant="secondary" className="text-xs shrink-0">
                        {blocks.filter((b) => b.visible).length}/{blocks.length} blocos
                    </Badge>
                </div>
                <CardDescription className="text-xs">
                    Configure os blocos exibidos no dashboard
                </CardDescription>
                <div className="flex items-center justify-between pt-2">
                    <span className="text-xs text-muted-foreground">
                        Exibir no Dashboard
                    </span>
                    <Switch
                        checked={sectionVisible}
                        onCheckedChange={handleSectionVisibleToggle}
                        disabled={saving}
                        aria-label={`${sectionVisible ? "Ocultar" : "Exibir"} secao ${integrationLabel} no dashboard`}
                    />
                </div>
            </CardHeader>

            <Separator />

            <CardContent className="pt-2 pb-3 flex-1">
                {blocks.length === 0 && (
                    <p className="text-xs text-muted-foreground py-1">
                        Integração com aba dedicada — sem blocos configuráveis. Use o botão acima para exibir ou ocultar a seção.
                    </p>
                )}
                <DndContext
                    sensors={blockSensors}
                    collisionDetection={closestCenter}
                    onDragEnd={handleBlockDragEnd}
                >
                    <SortableContext
                        items={blocks.map((b) => b.key)}
                        strategy={verticalListSortingStrategy}
                    >
                        <div className="flex flex-col">
                            {blocks.map((block) => (
                                <SortableBlockRow
                                    key={block.key}
                                    block={block}
                                    onToggle={handleBlockToggle}
                                    saving={saving}
                                >
                                    {block.key === "block_kpis" && (
                                        <>
                                            <div className="flex items-center justify-between mb-1">
                                                <span className="text-[10px] font-medium text-muted-foreground/60 uppercase tracking-wide">
                                                    Metricas
                                                </span>
                                                <Badge variant="outline" className="text-[10px] h-4 px-1">
                                                    {visibleMetricCount}/{metrics.length}
                                                </Badge>
                                            </div>
                                            <DndContext
                                                sensors={metricSensors}
                                                collisionDetection={closestCenter}
                                                onDragEnd={handleMetricDragEnd}
                                            >
                                                <SortableContext
                                                    items={metrics.map((m) => m.key)}
                                                    strategy={verticalListSortingStrategy}
                                                >
                                                    <div className="flex flex-col">
                                                        {metrics.map((metric) => (
                                                            <SortableMetricRow
                                                                key={metric.key}
                                                                metric={metric}
                                                                onToggle={handleMetricToggle}
                                                                saving={saving}
                                                            />
                                                        ))}
                                                    </div>
                                                </SortableContext>
                                            </DndContext>
                                        </>
                                    )}
                                </SortableBlockRow>
                            ))}
                        </div>
                    </SortableContext>
                </DndContext>
            </CardContent>
        </Card>
    );
}

/* ── Abas fixas do dashboard ─────────────────────────────────── */
const TAB_META = {
    resumo:    { label: "Resumo",    Icon: BarChart3 },
    aquisicao: { label: "Aquisição", Icon: Target },
    trafego:   { label: "Tráfego",   Icon: Globe },
    leads:     { label: "Leads",     Icon: Users },
};

const DEFAULT_TAB_ORDER = ["resumo", "aquisicao", "trafego", "leads"];

function TabTemplateCards({ project, initialTabConfig, availableTemplates }) {
    const [tabConfig, setTabConfig] = useState(initialTabConfig);
    const [tabOrder, setTabOrder] = useState(() => {
        const sorted = [...DEFAULT_TAB_ORDER].sort((a, b) => {
            const oA = initialTabConfig[a]?.order ?? DEFAULT_TAB_ORDER.indexOf(a);
            const oB = initialTabConfig[b]?.order ?? DEFAULT_TAB_ORDER.indexOf(b);
            return oA - oB;
        });
        return sorted;
    });
    const [saving, setSaving] = useState(false);

    const tabSensors = useSensors(
        useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
    );

    const persist = useCallback(
        (updated) => {
            setSaving(true);
            router.put(
                route("projetos.dashboard-config.tabs", project.id),
                { tab_config: updated },
                {
                    preserveScroll: true,
                    onSuccess: () => {
                        toast.success("Configuração salva.");
                        setSaving(false);
                    },
                    onError: () => {
                        toast.error("Erro ao salvar.");
                        setSaving(false);
                    },
                }
            );
        },
        [project.id]
    );

    const handleTabDragEnd = useCallback(
        ({ active, over }) => {
            if (!over || active.id === over.id) return;
            const oldIndex = tabOrder.indexOf(active.id);
            const newIndex = tabOrder.indexOf(over.id);
            const newOrder = arrayMove(tabOrder, oldIndex, newIndex);
            setTabOrder(newOrder);

            const updated = { ...tabConfig };
            newOrder.forEach((id, i) => {
                updated[id] = { ...(updated[id] ?? {}), order: i };
            });
            setTabConfig(updated);
            persist(updated);
        },
        [tabOrder, tabConfig, persist]
    );

    const handleVisibilityToggle = useCallback(
        (tabId, checked) => {
            const updated = { ...tabConfig, [tabId]: { ...tabConfig[tabId], visible: checked } };
            setTabConfig(updated);
            persist(updated);
        },
        [tabConfig, persist]
    );

    const handleTemplateChange = useCallback(
        (tabId, templateId) => {
            const updated = { ...tabConfig, [tabId]: { ...tabConfig[tabId], template_id: templateId } };
            setTabConfig(updated);
            persist(updated);
        },
        [tabConfig, persist]
    );

    return (
        <DndContext
            sensors={tabSensors}
            collisionDetection={closestCenter}
            onDragEnd={handleTabDragEnd}
        >
            <SortableContext items={tabOrder} strategy={rectSortingStrategy}>
                <div className="grid gap-4 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
                    {tabOrder.map((id) => {
                        const { label, Icon } = TAB_META[id];
                        const cfg = tabConfig[id] ?? { visible: true, template_id: null };
                        const templates = availableTemplates[id] ?? [];

                        return (
                            <SortableCard key={id} id={id}>
                                {({ dragHandleProps }) => (
                                    <Card className={!cfg.visible ? "opacity-60" : ""}>
                                        <CardHeader className="pb-3">
                                            <div className="flex items-start justify-between gap-2">
                                                <CardTitle className="flex items-center gap-2 text-sm font-semibold leading-tight">
                                                    <button
                                                        {...dragHandleProps}
                                                        className="cursor-grab active:cursor-grabbing text-muted-foreground/50 hover:text-muted-foreground transition-colors shrink-0 touch-none"
                                                        tabIndex={-1}
                                                        aria-label="Arrastar para reordenar aba"
                                                    >
                                                        <GripVertical className="h-4 w-4" />
                                                    </button>
                                                    <Icon className="h-4 w-4" />
                                                    {label}
                                                </CardTitle>
                                                <Switch
                                                    checked={cfg.visible}
                                                    onCheckedChange={(v) => handleVisibilityToggle(id, v)}
                                                    disabled={saving}
                                                    aria-label={`${cfg.visible ? "Ocultar" : "Exibir"} aba ${label}`}
                                                />
                                            </div>
                                        </CardHeader>
                                        <Separator />
                                        <CardContent className="pt-3 pb-3">
                                            <div className="flex flex-col gap-1.5">
                                                <span className="text-[10px] font-medium text-muted-foreground/60 uppercase tracking-wide">
                                                    Template
                                                </span>
                                                <Select
                                                    value={cfg.template_id ?? ""}
                                                    onValueChange={(v) => handleTemplateChange(id, v)}
                                                    disabled={saving || !cfg.visible}
                                                >
                                                    <SelectTrigger className="h-8 text-xs w-full">
                                                        <SelectValue placeholder="Padrão" />
                                                    </SelectTrigger>
                                                    <SelectContent>
                                                        {templates.map((t) => (
                                                            <SelectItem key={t.id} value={t.id}>
                                                                {t.name}
                                                            </SelectItem>
                                                        ))}
                                                    </SelectContent>
                                                </Select>
                                            </div>
                                        </CardContent>
                                    </Card>
                                )}
                            </SortableCard>
                        );
                    })}
                </div>
            </SortableContext>
        </DndContext>
    );
}

/* ── Pagina principal ─────────────────────────────────────────── */
export default function DashboardConfig({ project, configs: initialConfigs, trendMode: initialTrendMode = "on", tabConfig: initialTabConfig = {}, availableTemplates = {} }) {
    const [configs, setConfigs] = useState(initialConfigs);
    const [trendMode, setTrendMode] = useState(initialTrendMode);
    const [savingSettings, setSavingSettings] = useState(false);

    const cardSensors = useSensors(
        useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
    );

    const persistSettings = useCallback(
        (updatedConfigs, updatedTrendMode) => {
            setSavingSettings(true);
            router.put(
                route("projetos.dashboard-config.settings", project.id),
                {
                    integrations_order: updatedConfigs.map((c, i) => ({
                        integration_type: c.integration_type,
                        order: i,
                    })),
                    trend_mode: updatedTrendMode,
                },
                {
                    preserveScroll: true,
                    onSuccess: () => {
                        toast.success("Configuracao salva.");
                        setSavingSettings(false);
                    },
                    onError: () => {
                        toast.error("Erro ao salvar.");
                        setSavingSettings(false);
                    },
                }
            );
        },
        [project.id]
    );

    const handleCardDragEnd = useCallback(
        ({ active, over }) => {
            if (!over || active.id === over.id) return;
            const oldIndex = configs.findIndex((c) => c.integration_type === active.id);
            const newIndex = configs.findIndex((c) => c.integration_type === over.id);
            const reordered = arrayMove(configs, oldIndex, newIndex);
            setConfigs(reordered);
            persistSettings(reordered, trendMode);
        },
        [configs, trendMode, persistSettings]
    );

    const handleTrendModeChange = useCallback(
        (value) => {
            setTrendMode(value);
            persistSettings(configs, value);
        },
        [configs, persistSettings]
    );

    return (
        <AppLayout>
            <Head title={`Editar Dashboard - ${project.name}`} />

            <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <PageHeader
                    title="Editar Dashboard"
                    breadcrumb={[
                        { label: "Projetos", href: "projetos.index", icon: FolderKanban },
                        { label: project.name, href: "projetos.edit", params: project.id },
                    ]}
                />

                <div className="flex items-center gap-2 flex-wrap">
                    <MagicWandButton projectId={project.id} />
                    {configs.length > 0 && (
                        <>
                            <span className="text-xs text-muted-foreground whitespace-nowrap">
                                Comparativo
                            </span>
                            <Select
                                value={trendMode}
                                onValueChange={handleTrendModeChange}
                                disabled={savingSettings}
                            >
                                <SelectTrigger className="w-44 h-8 text-xs">
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {TREND_MODE_OPTIONS.map((opt) => (
                                        <SelectItem key={opt.value} value={opt.value}>
                                            {opt.label}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </>
                    )}
                </div>
            </div>

            <TabTemplateCards
                project={project}
                initialTabConfig={initialTabConfig}
                availableTemplates={availableTemplates}
            />

            {configs.length === 0 ? (
                <div className="rounded-md border border-dashed p-12 flex flex-col items-center gap-3 text-center text-muted-foreground">
                    <Settings2 className="h-10 w-10 opacity-40" />
                    <div>
                        <p className="font-medium">Nenhuma integracao ativa</p>
                        <p className="text-sm mt-1">
                            Configure integracoes para este projeto antes de
                            configurar o dashboard.
                        </p>
                    </div>
                    <Button variant="outline" size="sm" asChild>
                        <Link href={route("projetos.edit", project.id)}>
                            Ir para configuracoes do projeto
                        </Link>
                    </Button>
                </div>
            ) : (
                <DndContext
                    sensors={cardSensors}
                    collisionDetection={closestCenter}
                    onDragEnd={handleCardDragEnd}
                >
                    <SortableContext
                        items={configs.map((c) => c.integration_type)}
                        strategy={rectSortingStrategy}
                    >
                        <div className="grid gap-4 grid-cols-1 sm:grid-cols-2 xl:grid-cols-4">
                            {configs.map((config) => (
                                <SortableCard
                                    key={config.integration_type}
                                    id={config.integration_type}
                                >
                                    {({ dragHandleProps }) => (
                                        <IntegrationConfigCard
                                            project={project}
                                            integrationType={config.integration_type}
                                            integrationLabel={config.integration_label}
                                            initialMetrics={config.metrics}
                                            initialBlocks={config.blocks}
                                            initialSectionVisible={config.section_visible ?? false}
                                            dragHandleProps={dragHandleProps}
                                        />
                                    )}
                                </SortableCard>
                            ))}
                        </div>
                    </SortableContext>
                </DndContext>
            )}
        </AppLayout>
    );
}
