import { useMemo } from "react";
import {
    LineChart, Line,
    AreaChart, Area,
    BarChart, Bar, Cell,
    ComposedChart,
    PieChart, Pie,
    XAxis, YAxis, CartesianGrid, Tooltip,
    ResponsiveContainer, Legend,
} from "recharts";
import { Monitor, Smartphone, Tablet, Tv } from "lucide-react";

import { useDashboardFilters } from "@/context/DashboardFiltersContext";
import { CHART_COLORS } from "@/Components/Dashboard/chartColors";
import KpiCard from "@/Components/Dashboard/KpiCard";
import ChartCard from "@/Components/Dashboard/ChartCard";
import DashboardSkeleton from "@/Components/Dashboard/DashboardSkeleton";
import TemplateRenderer from "@/Components/Dashboard/TemplateRenderer";
import { layoutHasForeignData } from "@/lib/blockGrid";
import { ProviderIcons } from "@/Components/Dashboard/integrationIcons";
import { Card, CardContent } from "@/Components/ui/card";
import {
    axisStyle, tickDate, tooltipDate,
    fmtNumber, fmtPercent,
    buildSourceMediumTimeSeries,
    deviceLabel, deviceColor, shortenPath,
} from "./trafegoDataHelpers";

/* ── Tooltips ────────────────────────────────────────────── */

function DateTooltip({ active, payload, label }) {
    if (!active || !payload?.length) return null;
    return (
        <div className="rounded-md border bg-card px-3 py-2 text-xs shadow-md">
            <p className="font-medium mb-1">{tooltipDate(label)}</p>
            {payload.map((p) => (
                <p key={p.dataKey} style={{ color: p.color }}>
                    {p.name}: <span className="font-semibold">{fmtNumber(p.value)}</span>
                </p>
            ))}
        </div>
    );
}

function PercentTooltip({ active, payload, label }) {
    if (!active || !payload?.length) return null;
    return (
        <div className="rounded-md border bg-card px-3 py-2 text-xs shadow-md">
            <p className="font-medium mb-1">{tooltipDate(label)}</p>
            {payload.map((p) => (
                <p key={p.dataKey} style={{ color: p.color }}>
                    {p.name}: <span className="font-semibold">{fmtPercent(p.value)}</span>
                </p>
            ))}
        </div>
    );
}

function StackedTooltip({ active, payload, label }) {
    if (!active || !payload?.length) return null;
    const total = payload.reduce((s, p) => s + (p.value ?? 0), 0);
    return (
        <div className="rounded-md border bg-card px-3 py-2 text-xs shadow-md">
            <p className="font-medium mb-1">{tooltipDate(label)}</p>
            {payload.map((p) => (
                <p key={p.dataKey} style={{ color: p.color }}>
                    {p.name}: <span className="font-semibold">{fmtNumber(p.value)}</span>
                </p>
            ))}
            <p className="mt-1 border-t pt-1 font-medium">Total: {fmtNumber(total)}</p>
        </div>
    );
}

function DevicePieTooltip({ active, payload }) {
    if (!active || !payload?.length) return null;
    const d = payload[0];
    return (
        <div className="rounded-md border bg-card px-3 py-2 text-xs shadow-md">
            <p style={{ color: d.payload.fill }}>{d.name}</p>
            <p className="font-semibold">{fmtNumber(d.value)} sessões ({d.payload.pct}%)</p>
        </div>
    );
}

const DEVICE_ICON = { desktop: Monitor, mobile: Smartphone, tablet: Tablet, smart_tv: Tv };

function renderPieLabel({ cx, cy, midAngle, innerRadius, outerRadius, pct }) {
    if (pct < 5) return null;
    const RADIAN = Math.PI / 180;
    const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
    const x = cx + radius * Math.cos(-midAngle * RADIAN);
    const y = cy + radius * Math.sin(-midAngle * RADIAN);
    return (
        <text x={x} y={y} fill="#fff" textAnchor="middle" dominantBaseline="central" fontSize={12} fontWeight={600}>
            {pct}%
        </text>
    );
}

function LandingPageTable({ data }) {
    if (!data?.length) return null;
    return (
        <div className="rounded-md border overflow-auto">
            <table className="w-full text-xs">
                <thead>
                    <tr className="border-b bg-muted/30">
                        <th className="px-2 py-1.5 text-left font-medium">Página</th>
                        <th className="px-2 py-1.5 text-right font-medium">Sessões</th>
                        <th className="px-2 py-1.5 text-right font-medium hidden sm:table-cell">Usuários</th>
                        <th className="px-2 py-1.5 text-right font-medium hidden md:table-cell">Engajadas</th>
                        <th className="px-2 py-1.5 text-right font-medium hidden sm:table-cell">Conversões</th>
                    </tr>
                </thead>
                <tbody>
                    {data.map((row, i) => {
                        const engRate = row.sessions > 0
                            ? ((row.engaged_sessions / row.sessions) * 100).toFixed(1) + "%"
                            : "–";
                        return (
                            <tr key={i} className="border-b last:border-0">
                                <td className="px-2 py-1.5 max-w-[280px] truncate" title={row.landing_page}>
                                    <span className="text-muted-foreground mr-1.5">{i + 1}</span>
                                    {shortenPath(row.landing_page)}
                                </td>
                                <td className="px-2 py-1.5 text-right tabular-nums">{fmtNumber(row.sessions)}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums hidden sm:table-cell">{fmtNumber(row.users_count)}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums hidden md:table-cell">{engRate}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums hidden sm:table-cell">{fmtNumber(row.conversions)}</td>
                            </tr>
                        );
                    })}
                </tbody>
            </table>
        </div>
    );
}

function SourceMediumTable({ data }) {
    if (!data?.length) return null;
    const totalSessions = data.reduce((s, r) => s + r.sessions, 0);
    return (
        <div className="rounded-md border overflow-auto">
            <table className="w-full text-xs">
                <thead>
                    <tr className="border-b bg-muted/30">
                        <th className="px-2 py-1.5 text-left font-medium">Source / Medium</th>
                        <th className="px-2 py-1.5 text-right font-medium">Sessões</th>
                        <th className="px-2 py-1.5 text-right font-medium hidden sm:table-cell">Usuários</th>
                        <th className="px-2 py-1.5 text-right font-medium hidden sm:table-cell">Engajadas</th>
                        <th className="px-2 py-1.5 text-right font-medium hidden md:table-cell">Conversões</th>
                        <th className="px-2 py-1.5 text-right font-medium">%</th>
                    </tr>
                </thead>
                <tbody>
                    {data.map((row, i) => {
                        const pct = totalSessions > 0
                            ? ((row.sessions / totalSessions) * 100).toFixed(1)
                            : "0";
                        return (
                            <tr key={i} className="border-b last:border-0">
                                <td className="px-2 py-1.5 max-w-[200px] truncate">
                                    <span className="text-muted-foreground mr-1.5">{i + 1}</span>
                                    {row.source_medium}
                                </td>
                                <td className="px-2 py-1.5 text-right tabular-nums">{fmtNumber(row.sessions)}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums hidden sm:table-cell">{fmtNumber(row.users_count)}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums hidden sm:table-cell">{fmtNumber(row.engaged_sessions)}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums hidden md:table-cell">{fmtNumber(row.conversions)}</td>
                                <td className="px-2 py-1.5 text-right tabular-nums text-muted-foreground">{pct}%</td>
                            </tr>
                        );
                    })}
                </tbody>
            </table>
        </div>
    );
}

function DeviceCard({ device, sessions, totalSessions }) {
    const Icon = DEVICE_ICON[device] ?? Monitor;
    const pct = totalSessions > 0 ? ((sessions / totalSessions) * 100).toFixed(1) : "0";
    const color = deviceColor(device);

    return (
        <Card className="relative">
            <ProviderIcons providers={["ga4"]} size={14} className="absolute right-2 top-2" />
            <CardContent className="flex items-center gap-3 px-4 py-3">
                <div className="rounded-md p-2" style={{ backgroundColor: color + "1A" }}>
                    <Icon className="h-5 w-5" style={{ color }} />
                </div>
                <div className="flex-1 min-w-0">
                    <p className="text-sm font-semibold">{deviceLabel(device)}</p>
                    <p className="text-xs text-muted-foreground">{fmtNumber(sessions)} sessões</p>
                </div>
                <p className="text-lg font-bold tabular-nums" style={{ color }}>{pct}%</p>
            </CardContent>
        </Card>
    );
}

/* ── Blocos ───────────────────────────────────────────────── */

function BlockKpis({ trafegoKpis, trends, trendMode }) {
    return (
        <div className="grid grid-cols-2 gap-3 sm:grid-cols-4 lg:grid-cols-7">
            <KpiCard label="Sessões"            value={trafegoKpis.sessoes ?? 0}             format="number"  trend={trends.sessoes} trendMode={trendMode} providers={["ga4"]} />
            <KpiCard label="Usuários"           value={trafegoKpis.usuarios ?? 0}            format="number"  trend={trends.usuarios} trendMode={trendMode} providers={["ga4"]} />
            <KpiCard label="Novos usuários"     value={trafegoKpis.novos_usuarios ?? 0}      format="number"  trend={trends.novos_usuarios} trendMode={trendMode} providers={["ga4"]} />
            <KpiCard label="Pageviews"          value={trafegoKpis.pageviews ?? 0}           format="number"  trend={trends.pageviews} trendMode={trendMode} providers={["ga4"]} />
            <KpiCard label="Sessões engajadas"  value={trafegoKpis.sessoes_engajadas ?? 0}   format="number"  trend={trends.sessoes_engajadas} trendMode={trendMode} providers={["ga4"]} />
            <KpiCard label="Tx. Engajamento"    value={trafegoKpis.taxa_engajamento ?? 0}    format="percent" trend={trends.taxa_engajamento} trendMode={trendMode} providers={["ga4"]} />
            <KpiCard label="Págs / Sessão"      value={trafegoKpis.paginas_por_sessao ?? 0}  format="number"  trend={trends.paginas_por_sessao} trendMode={trendMode} providers={["ga4"]} />
        </div>
    );
}

function BlockSessoesUsuarios({ readiness, ga4 }) {
    if (!readiness.hasTimeSeries || ga4.length === 0) return null;
    return (
        <ChartCard title="Sessões e Usuários ao longo do tempo" description="Sessões (área) e Usuários únicos (linha)" providers={["ga4"]}>
            <ResponsiveContainer width="100%" height="100%">
                <ComposedChart data={ga4} margin={{ top: 5, right: 10, left: 0, bottom: 5 }}>
                    <defs>
                        <linearGradient id="gradSessions" x1="0" y1="0" x2="0" y2="1">
                            <stop offset="5%"  stopColor={CHART_COLORS.blue}  stopOpacity={0.15} />
                            <stop offset="95%" stopColor={CHART_COLORS.blue}  stopOpacity={0} />
                        </linearGradient>
                    </defs>
                    <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
                    <XAxis dataKey="report_date" tick={axisStyle} tickFormatter={tickDate} />
                    <YAxis yAxisId="left" tick={axisStyle} />
                    <YAxis yAxisId="right" orientation="right" tick={axisStyle} />
                    <Tooltip content={<DateTooltip />} />
                    <Legend wrapperStyle={{ fontSize: 12 }} />
                    <Area yAxisId="left" type="monotone" dataKey="sessions" name="Sessões" stroke={CHART_COLORS.blue} strokeWidth={2} fill="url(#gradSessions)" dot={false} />
                    <Line yAxisId="right" type="monotone" dataKey="users_count" name="Usuários" stroke={CHART_COLORS.violet} strokeWidth={2} dot={false} />
                </ComposedChart>
            </ResponsiveContainer>
        </ChartCard>
    );
}

function BlockTaxaEngajamento({ readiness, engagementSeries }) {
    if (!readiness.hasTimeSeries || engagementSeries.length === 0) return null;
    return (
        <ChartCard title="Taxa de Engajamento" description="% de sessões engajadas por dia" providers={["ga4"]}>
            <ResponsiveContainer width="100%" height="100%">
                <AreaChart data={engagementSeries} margin={{ top: 5, right: 10, left: 0, bottom: 5 }}>
                    <defs>
                        <linearGradient id="gradEngRate" x1="0" y1="0" x2="0" y2="1">
                            <stop offset="5%"  stopColor={CHART_COLORS.green} stopOpacity={0.2} />
                            <stop offset="95%" stopColor={CHART_COLORS.green} stopOpacity={0} />
                        </linearGradient>
                    </defs>
                    <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
                    <XAxis dataKey="report_date" tick={axisStyle} tickFormatter={tickDate} />
                    <YAxis tick={axisStyle} tickFormatter={(v) => `${v}%`} />
                    <Tooltip content={<PercentTooltip />} />
                    <Area type="monotone" dataKey="taxa_engajamento" name="Tx. Engajamento" stroke={CHART_COLORS.green} strokeWidth={2} fill="url(#gradEngRate)" dot={false} />
                </AreaChart>
            </ResponsiveContainer>
        </ChartCard>
    );
}

function BlockEngajamento({ readiness, ga4 }) {
    if (!readiness.hasTimeSeries || ga4.length === 0) return null;
    return (
        <ChartCard title="Engajamento" description="Sessões totais vs. sessões engajadas" providers={["ga4"]}>
            <ResponsiveContainer width="100%" height="100%">
                <AreaChart data={ga4} margin={{ top: 5, right: 10, left: 0, bottom: 5 }}>
                    <defs>
                        <linearGradient id="gradSess2" x1="0" y1="0" x2="0" y2="1">
                            <stop offset="5%"  stopColor={CHART_COLORS.blue}  stopOpacity={0.15} />
                            <stop offset="95%" stopColor={CHART_COLORS.blue}  stopOpacity={0} />
                        </linearGradient>
                        <linearGradient id="gradEngaged" x1="0" y1="0" x2="0" y2="1">
                            <stop offset="5%"  stopColor={CHART_COLORS.green} stopOpacity={0.2} />
                            <stop offset="95%" stopColor={CHART_COLORS.green} stopOpacity={0} />
                        </linearGradient>
                    </defs>
                    <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
                    <XAxis dataKey="report_date" tick={axisStyle} tickFormatter={tickDate} />
                    <YAxis tick={axisStyle} />
                    <Tooltip content={<DateTooltip />} />
                    <Legend wrapperStyle={{ fontSize: 12 }} />
                    <Area type="monotone" dataKey="sessions" name="Sessões" stroke={CHART_COLORS.blue} fill="url(#gradSess2)" strokeWidth={2} dot={false} />
                    <Area type="monotone" dataKey="engaged_sessions" name="Sessões engajadas" stroke={CHART_COLORS.green} fill="url(#gradEngaged)" strokeWidth={2} dot={false} />
                </AreaChart>
            </ResponsiveContainer>
        </ChartCard>
    );
}

function BlockSourceMediumTimeline({ readiness, sourceMediumTs }) {
    if (!readiness.hasSourceMedium || sourceMediumTs.series.length < 2) return null;
    return (
        <ChartCard title="Sessões por Source / Medium ao longo do tempo" description="Top canais empilhados por dia" providers={["ga4"]}>
            <ResponsiveContainer width="100%" height="100%">
                <AreaChart data={sourceMediumTs.series} margin={{ top: 5, right: 10, left: 0, bottom: 5 }}>
                    <CartesianGrid strokeDasharray="3 3" stroke="hsl(var(--border))" />
                    <XAxis dataKey="date" tick={axisStyle} tickFormatter={tickDate} />
                    <YAxis tick={axisStyle} allowDecimals={false} />
                    <Tooltip content={<StackedTooltip />} />
                    <Legend wrapperStyle={{ fontSize: 12 }} />
                    {sourceMediumTs.channels.map((ch) => (
                        <Area key={ch.key} type="monotone" dataKey={ch.key} name={ch.label} stroke={ch.color} fill={ch.color} fillOpacity={0.15} strokeWidth={2} stackId="sm" dot={false} />
                    ))}
                </AreaChart>
            </ResponsiveContainer>
        </ChartCard>
    );
}

function BlockSourceMediumRanking({ readiness, ga4BySourceMedium }) {
    if (!readiness.hasSourceMedium) return null;
    return <SourceMediumTable data={ga4BySourceMedium} />;
}

function BlockLandingPages({ readiness, ga4ByLandingPage }) {
    if (!readiness.hasLandingPages) return null;
    return <LandingPageTable data={ga4ByLandingPage} />;
}

function BlockDevicesCards({ readiness, ga4ByDevice, totalDeviceSessions }) {
    if (!readiness.hasDeviceBreakdown || ga4ByDevice.length === 0) return null;
    return (
        <div className="grid grid-cols-2 gap-3">
            {ga4ByDevice.map((d) => (
                <DeviceCard key={d.device_type} device={d.device_type} sessions={d.sessions} totalSessions={totalDeviceSessions} />
            ))}
        </div>
    );
}

function BlockDevicesDonut({ readiness, devicePieData }) {
    if (!readiness.hasDeviceBreakdown || devicePieData.length === 0) return null;
    return (
        <ChartCard title="Distribuição por dispositivo" height="h-[240px]" providers={["ga4"]}>
            <ResponsiveContainer width="100%" height="100%">
                <PieChart>
                    <Pie data={devicePieData} dataKey="value" cx="50%" cy="50%" innerRadius={45} outerRadius={80} strokeWidth={2} stroke="hsl(var(--card))" label={renderPieLabel} labelLine={false}>
                        {devicePieData.map((entry) => (<Cell key={entry.name} fill={entry.fill} />))}
                    </Pie>
                    <Tooltip content={<DevicePieTooltip />} />
                    <Legend wrapperStyle={{ fontSize: 12 }} formatter={(value, entry) => (<span style={{ color: entry.color }}>{value}</span>)} />
                </PieChart>
            </ResponsiveContainer>
        </ChartCard>
    );
}

const TRAFEGO_DISPATCH = {
    trafego_kpis:                    BlockKpis,
    trafego_sessoes_usuarios:        BlockSessoesUsuarios,
    trafego_taxa_engajamento:        BlockTaxaEngajamento,
    trafego_engajamento:             BlockEngajamento,
    trafego_source_medium_timeline:  BlockSourceMediumTimeline,
    trafego_source_medium_ranking:   BlockSourceMediumRanking,
    trafego_landing_pages:           BlockLandingPages,
    trafego_devices_cards:           BlockDevicesCards,
    trafego_devices_donut:           BlockDevicesDonut,
};

/* ── Main Component ──────────────────────────────────────── */

export default function TrafegoTab({ trendMode = "on", layout = null }) {
    const { data, loading } = useDashboardFilters();

    const ga4                    = data?.ga4 ?? [];
    const ga4BySourceMedium      = data?.ga4BySourceMedium ?? [];
    const ga4BySourceMediumDaily = data?.ga4BySourceMediumDaily ?? [];
    const ga4ByLandingPage       = data?.ga4ByLandingPage ?? [];
    const ga4ByDevice            = data?.ga4ByDevice ?? [];
    const trafegoKpis            = data?.trafegoKpis ?? {};
    const trends                 = data?.trends?.trafegoKpis ?? {};
    const readiness              = data?.trafegoReadiness ?? {};

    const engagementSeries = useMemo(
        () => ga4.map((row) => ({
            report_date: row.report_date,
            taxa_engajamento: row.sessions > 0 ? Math.round((row.engaged_sessions / row.sessions) * 1000) / 10 : 0,
            paginas_por_sessao: row.sessions > 0 ? Math.round((row.pageviews / row.sessions) * 10) / 10 : 0,
        })),
        [ga4],
    );

    const sourceMediumTs = useMemo(
        () => buildSourceMediumTimeSeries(ga4BySourceMediumDaily, ga4BySourceMedium.slice(0, 6)),
        [ga4BySourceMediumDaily, ga4BySourceMedium],
    );

    const { devicePieData, totalDeviceSessions } = useMemo(() => {
        const total = ga4ByDevice.reduce((s, d) => s + d.sessions, 0);
        const pie = ga4ByDevice.map((d) => ({
            name: deviceLabel(d.device_type),
            value: d.sessions,
            fill: deviceColor(d.device_type),
            pct: total > 0 ? Math.round((d.sessions / total) * 1000) / 10 : 0,
            device: d.device_type,
        }));
        return { devicePieData: pie, totalDeviceSessions: total };
    }, [ga4ByDevice]);

    if (loading) return <DashboardSkeleton />;

    // Não bloqueia a aba quando o template tem um bloco de outro provider com dado (ex.: cvcrm).
    if (!readiness.hasData && !layoutHasForeignData(layout, data)) {
        return (
            <Card>
                <CardContent className="py-12 text-center">
                    <p className="text-muted-foreground">Nenhum dado de tráfego (GA4) no período selecionado.</p>
                </CardContent>
            </Card>
        );
    }

    const blockProps = {
        trafegoKpis, trends,
        ga4, ga4BySourceMedium, ga4BySourceMediumDaily, ga4ByLandingPage, ga4ByDevice,
        engagementSeries, sourceMediumTs, devicePieData, totalDeviceSessions,
        readiness,
    };

    return (
        <TemplateRenderer
            rows={layout}
            dispatch={TRAFEGO_DISPATCH}
            blockProps={blockProps}
            trendMode={trendMode}
        />
    );
}
