import { BarChart3, LineChart as LineChartIcon, PieChart, TrendingUp } from 'lucide-react';
import React from 'react';
import {
    Area,
    AreaChart,
    Bar,
    BarChart,
    CartesianGrid,
    Cell,
    Legend,
    Line,
    LineChart,
    Pie,
    PieChart as RechartsPieChart,
    ResponsiveContainer,
    Tooltip,
    XAxis,
    YAxis,
} from 'recharts';

// ─── Types ────────────────────────────────────────────────────────────────────

export type ChartType = 'line' | 'bar' | 'area' | 'pie' | 'donut';

export interface ChartDataset {
    key: string;
    label: string;
    data: number[];
    color: string;
}

export interface ChartData {
    labels: string[];
    datasets: ChartDataset[];
}

interface ReportChartProps {
    type: ChartType;
    data: ChartData;
    availableTypes: ChartType[];
    onTypeChange: (type: ChartType) => void;
    title?: string;
    subtitle?: string;
}

// ─── Chart type switcher icons ────────────────────────────────────────────────

const chartTypeConfig: Record<ChartType, { icon: React.ElementType; label: string }> = {
    line:  { icon: LineChartIcon, label: 'Line' },
    bar:   { icon: BarChart3,     label: 'Bar' },
    area:  { icon: TrendingUp,    label: 'Area' },
    pie:   { icon: PieChart,      label: 'Pie' },
    donut: { icon: PieChart,      label: 'Donut' },
};

// Reads the brand primary color from the CSS variable set by the theme system
function getPrimary(): string {
    if (typeof document === 'undefined') return '#008060';
    return getComputedStyle(document.documentElement).getPropertyValue('--primary').trim() || '#008060';
}

function getPieColors(): string[] {
    return [getPrimary(), '#6366f1', '#f59e0b', '#ef4444', '#3b82f6', '#8b5cf6', '#10b981', '#f97316'];
}

// Replace backend-hardcoded #008060 with the live primary color in dataset colors
function resolveDatasetColor(color: string): string {
    return color === '#008060' ? getPrimary() : color;
}

// ─── Data adapter ─────────────────────────────────────────────────────────────

function toRechartsData(data: ChartData): Record<string, string | number>[] {
    return data.labels.map((label, i) => {
        const row: Record<string, string | number> = { label };
        data.datasets.forEach((ds) => {
            row[ds.key] = ds.data[i] ?? 0;
        });
        return row;
    });
}

function toPieData(data: ChartData): { name: string; value: number }[] {
    if (!data.datasets.length) return [];
    const ds = data.datasets[0];
    return data.labels.map((label, i) => ({ name: label, value: ds.data[i] ?? 0 }));
}

// ─── Chart renderers ──────────────────────────────────────────────────────────

function LineChartView({ data }: { data: ChartData }) {
    const rows = toRechartsData(data);
    return (
        <ResponsiveContainer width="100%" height={320}>
            <LineChart data={rows} margin={{ top: 8, right: 24, left: 0, bottom: 8 }}>
                <CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
                <XAxis dataKey="label" tick={{ fontSize: 11 }} tickLine={false} axisLine={false} />
                <YAxis tick={{ fontSize: 11 }} tickLine={false} axisLine={false} width={60} />
                <Tooltip contentStyle={{ borderRadius: 8, border: '1px solid #e3e3e3', fontSize: 12 }} />
                <Legend wrapperStyle={{ fontSize: 12 }} />
                {data.datasets.map((ds) => (
                    <Line
                        key={ds.key}
                        type="monotone"
                        dataKey={ds.key}
                        name={ds.label}
                        stroke={resolveDatasetColor(ds.color)}
                        strokeWidth={2}
                        dot={{ r: 3 }}
                        activeDot={{ r: 5 }}
                    />
                ))}
            </LineChart>
        </ResponsiveContainer>
    );
}

function BarChartView({ data }: { data: ChartData }) {
    const rows = toRechartsData(data);
    return (
        <ResponsiveContainer width="100%" height={320}>
            <BarChart data={rows} margin={{ top: 8, right: 24, left: 0, bottom: 8 }}>
                <CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
                <XAxis dataKey="label" tick={{ fontSize: 11 }} tickLine={false} axisLine={false} />
                <YAxis tick={{ fontSize: 11 }} tickLine={false} axisLine={false} width={60} />
                <Tooltip contentStyle={{ borderRadius: 8, border: '1px solid #e3e3e3', fontSize: 12 }} />
                <Legend wrapperStyle={{ fontSize: 12 }} />
                {data.datasets.map((ds) => (
                    <Bar key={ds.key} dataKey={ds.key} name={ds.label} fill={resolveDatasetColor(ds.color)} radius={[3, 3, 0, 0]} />
                ))}
            </BarChart>
        </ResponsiveContainer>
    );
}

function AreaChartView({ data }: { data: ChartData }) {
    const rows = toRechartsData(data);
    return (
        <ResponsiveContainer width="100%" height={320}>
            <AreaChart data={rows} margin={{ top: 8, right: 24, left: 0, bottom: 8 }}>
                <defs>
                    {data.datasets.map((ds) => (
                        <linearGradient key={ds.key} id={`grad-${ds.key}`} x1="0" y1="0" x2="0" y2="1">
                            <stop offset="5%" stopColor={resolveDatasetColor(ds.color)} stopOpacity={0.3} />
                            <stop offset="95%" stopColor={resolveDatasetColor(ds.color)} stopOpacity={0} />
                        </linearGradient>
                    ))}
                </defs>
                <CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
                <XAxis dataKey="label" tick={{ fontSize: 11 }} tickLine={false} axisLine={false} />
                <YAxis tick={{ fontSize: 11 }} tickLine={false} axisLine={false} width={60} />
                <Tooltip contentStyle={{ borderRadius: 8, border: '1px solid #e3e3e3', fontSize: 12 }} />
                <Legend wrapperStyle={{ fontSize: 12 }} />
                {data.datasets.map((ds) => (
                    <Area
                        key={ds.key}
                        type="monotone"
                        dataKey={ds.key}
                        name={ds.label}
                        stroke={resolveDatasetColor(ds.color)}
                        strokeWidth={2}
                        fill={`url(#grad-${ds.key})`}
                    />
                ))}
            </AreaChart>
        </ResponsiveContainer>
    );
}

function PieChartView({ data, donut = false }: { data: ChartData; donut?: boolean }) {
    const pieData = toPieData(data);
    const innerRadius = donut ? '55%' : 0;
    const palette = getPieColors();

    return (
        <ResponsiveContainer width="100%" height={320}>
            <RechartsPieChart>
                <Pie
                    data={pieData}
                    cx="50%"
                    cy="50%"
                    innerRadius={innerRadius}
                    outerRadius="70%"
                    dataKey="value"
                    label={({ cx, cy, midAngle, innerRadius, outerRadius, percent }) => {
                        if (percent < 0.06) return null;
                        const RADIAN = Math.PI / 180;
                        const r = innerRadius + (outerRadius - innerRadius) * 0.55;
                        const x = cx + r * Math.cos(-midAngle * RADIAN);
                        const y = cy + r * Math.sin(-midAngle * RADIAN);
                        return (
                            <text x={x} y={y} fill="#fff" textAnchor="middle" dominantBaseline="central" fontSize={11} fontWeight={600}>
                                {`${(percent * 100).toFixed(0)}%`}
                            </text>
                        );
                    }}
                    labelLine={false}
                >
                    {pieData.map((_, index) => (
                        <Cell key={index} fill={palette[index % palette.length]} />
                    ))}
                </Pie>
                <Tooltip contentStyle={{ borderRadius: 8, border: '1px solid #e3e3e3', fontSize: 12 }} />
                <Legend wrapperStyle={{ fontSize: 12 }} />
            </RechartsPieChart>
        </ResponsiveContainer>
    );
}

// ─── Main component ───────────────────────────────────────────────────────────

export default function ReportChart({ type, data, availableTypes, onTypeChange, title = 'Chart', subtitle }: ReportChartProps) {
    const isEmpty = !data.labels.length || !data.datasets.length;

    return (
        <div className="h-full rounded-xl border border-[#d8d8d8] bg-white shadow-sm">
            {/* Header row */}
            <div className="flex items-center justify-between border-b border-[#e3e3e3] px-4 py-3">
                <div>
                    <span className="text-sm font-semibold text-[#202223]">{title}</span>
                    {subtitle && <p className="text-xs text-[#6d7175]">{subtitle}</p>}
                </div>
                <div className="flex items-center gap-1">
                    {availableTypes.map((t) => {
                        const cfg = chartTypeConfig[t];
                        if (!cfg) return null;
                        const Icon = cfg.icon;
                        return (
                            <button
                                key={t}
                                type="button"
                                onClick={() => onTypeChange(t)}
                                title={cfg.label}
                                className={`flex items-center gap-1 rounded px-2.5 py-1 text-xs font-medium transition-colors ${
                                    type === t
                                        ? 'bg-primary text-white'
                                        : 'border border-[#d8d8d8] bg-white text-[#6d7175] hover:bg-[#f6f6f7]'
                                }`}
                            >
                                <Icon className="h-3.5 w-3.5" />
                                <span className="hidden sm:inline">{cfg.label}</span>
                            </button>
                        );
                    })}
                </div>
            </div>

            {/* Chart area */}
            <div className="p-4">
                {isEmpty ? (
                    <div className="flex h-64 items-center justify-center text-sm text-[#6d7175]">
                        Generate a report to see the chart
                    </div>
                ) : (
                    <>
                        {type === 'line'  && <LineChartView data={data} />}
                        {type === 'bar'   && <BarChartView data={data} />}
                        {type === 'area'  && <AreaChartView data={data} />}
                        {type === 'pie'   && <PieChartView data={data} />}
                        {type === 'donut' && <PieChartView data={data} donut />}
                    </>
                )}
            </div>
        </div>
    );
}
