'use client';

import React, { useMemo } from 'react';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  ArcElement,
  Title,
  Tooltip,
  Legend,
  Filler,
  type ChartOptions,
} from 'chart.js';
import { Line, Bar, Doughnut } from 'react-chartjs-2';
import { useSimulation } from '@/contexts/SimulationContext';
import { formatCurrencyShort, formatCurrency } from '@/lib/formatters';

// Register ChartJS components
ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  BarElement,
  ArcElement,
  Title,
  Tooltip,
  Legend,
  Filler
);

// ─── Color palette ──────────────────────────────────────────────────────────

const COLORS = {
  capital: { bg: 'rgba(37, 99, 235, 0.15)', border: 'rgb(37, 99, 235)' },
  interest: { bg: 'rgba(245, 158, 11, 0.15)', border: 'rgb(245, 158, 11)' },
  insurance: { bg: 'rgba(139, 92, 246, 0.15)', border: 'rgb(139, 92, 246)' },
  charges: { bg: 'rgba(107, 114, 128, 0.15)', border: 'rgb(107, 114, 128)' },
  rent: { bg: 'rgba(239, 68, 68, 0.15)', border: 'rgb(239, 68, 68)' },
  projected: { bg: 'rgba(37, 99, 235, 0.15)', border: 'rgb(37, 99, 235)' },
  resale: { bg: 'rgba(5, 150, 105, 0.15)', border: 'rgb(5, 150, 105)' },
  negative: { bg: 'rgba(220, 38, 38, 0.15)', border: 'rgb(220, 38, 38)' },
};

const defaultTooltipOptions = {
  mode: 'index' as const,
  intersect: false,
  backgroundColor: 'rgba(15, 23, 42, 0.9)',
  titleColor: '#fff',
  bodyColor: '#cbd5e1',
  borderColor: 'rgba(148, 163, 184, 0.3)',
  borderWidth: 1,
  cornerRadius: 8,
  padding: 12,
  bodySpacing: 6,
  titleSpacing: 4,
  usePointStyle: true,
};

const defaultLegendOptions = {
  position: 'bottom' as const,
  labels: {
    usePointStyle: true,
    pointStyle: 'circle',
    padding: 16,
    font: { size: 11 },
    color: '#64748b',
  },
};

// ─── Main Charts Component ─────────────────────────────────────────────────

export default function Charts() {
  const { results } = useSimulation();
  const data = results.yearlySummaries.filter((y) => y.year <= results.maxDuration);
  const labels = data.map((y) => `An ${y.year}`);

  return (
    <div className="space-y-6 animate-fade-in">
      <div className="grid grid-cols-1 xl:grid-cols-2 gap-6">
        {/* 1. Remaining balance over time */}
        <ChartCard title="Évolution du capital restant dû">
          <RemainingBalanceChart data={data} labels={labels} />
        </ChartCard>

        {/* 2. Capital vs Interest vs Insurance breakdown */}
        <ChartCard title="Répartition annuelle des paiements">
          <PaymentBreakdownChart data={data} labels={labels} />
        </ChartCard>

        {/* 3. Monthly comparison: rent vs projected */}
        <ChartCard title="Comparaison mensuelle : propriétaire vs locataire">
          <ComparisonChart data={data} labels={labels} />
        </ChartCard>

        {/* 4. Resale projection */}
        <ChartCard title="Projection de revente (plus/moins-value nette)">
          <ResaleChart data={data} labels={labels} />
        </ChartCard>
      </div>

      {/* Cost breakdown donut */}
      <ChartCard title="Répartition du coût total du crédit">
        <div className="max-w-sm mx-auto">
          <CostDonut />
        </div>
      </ChartCard>
    </div>
  );
}

// ─── Chart Components ───────────────────────────────────────────────────────

function RemainingBalanceChart({ data, labels }: ChartProps) {
  const { results } = useSimulation();

  const chartData = useMemo(() => {
    // Stack per-loan remaining balances
    const datasets = results.loanResults.map((lr, idx) => {
      const colors = [
        COLORS.capital,
        COLORS.interest,
        COLORS.insurance,
        COLORS.charges,
        COLORS.rent,
      ];
      const color = colors[idx % colors.length];

      return {
        label: lr.loan.name,
        data: data.map((y) => {
          const yearData = lr.yearly.find((yr) => yr.year === y.year);
          return yearData?.remaining ?? 0;
        }),
        borderColor: color.border,
        backgroundColor: color.bg,
        fill: true,
        tension: 0.3,
        pointRadius: 0,
        pointHitRadius: 10,
        borderWidth: 2,
      };
    });

    return { labels, datasets };
  }, [data, labels, results.loanResults]);

  const options: ChartOptions<'line'> = {
    responsive: true,
    maintainAspectRatio: false,
    interaction: defaultTooltipOptions,
    plugins: {
      tooltip: {
        ...defaultTooltipOptions,
        callbacks: {
          label: (ctx) => `${ctx.dataset.label}: ${formatCurrency(ctx.parsed.y ?? 0)}`,
        },
      },
      legend: defaultLegendOptions,
    },
    scales: {
      x: {
        grid: { display: false },
        ticks: { color: '#94a3b8', font: { size: 10 } },
      },
      y: {
        stacked: true,
        grid: { color: 'rgba(148, 163, 184, 0.1)' },
        ticks: {
          color: '#94a3b8',
          font: { size: 10 },
          callback: (v) => formatCurrencyShort(v as number),
        },
      },
    },
  };

  return (
    <div className="h-72">
      <Line data={chartData} options={options} />
    </div>
  );
}

function PaymentBreakdownChart({ data, labels }: ChartProps) {
  const chartData = useMemo(
    () => ({
      labels,
      datasets: [
        {
          label: 'Capital',
          data: data.map((y) => y.totalPrincipal),
          backgroundColor: COLORS.capital.border,
          borderRadius: 3,
        },
        {
          label: 'Intérêts',
          data: data.map((y) => y.totalInterest),
          backgroundColor: COLORS.interest.border,
          borderRadius: 3,
        },
        {
          label: 'Assurance',
          data: data.map((y) => y.totalInsurance),
          backgroundColor: COLORS.insurance.border,
          borderRadius: 3,
        },
      ],
    }),
    [data, labels]
  );

  const options: ChartOptions<'bar'> = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      tooltip: {
        ...defaultTooltipOptions,
        callbacks: {
          label: (ctx) => `${ctx.dataset.label}: ${formatCurrency(ctx.parsed.y ?? 0)}`,
        },
      },
      legend: defaultLegendOptions,
    },
    scales: {
      x: {
        stacked: true,
        grid: { display: false },
        ticks: { color: '#94a3b8', font: { size: 10 } },
      },
      y: {
        stacked: true,
        grid: { color: 'rgba(148, 163, 184, 0.1)' },
        ticks: {
          color: '#94a3b8',
          font: { size: 10 },
          callback: (v) => formatCurrencyShort(v as number),
        },
      },
    },
  };

  return (
    <div className="h-72">
      <Bar data={chartData} options={options} />
    </div>
  );
}

function ComparisonChart({ data, labels }: ChartProps) {
  const chartData = useMemo(
    () => ({
      labels,
      datasets: [
        {
          label: 'Mensualité propriétaire',
          data: data.map((y) => y.monthlyTotal),
          borderColor: COLORS.projected.border,
          backgroundColor: COLORS.projected.bg,
          fill: true,
          tension: 0.3,
          pointRadius: 2,
          pointHitRadius: 10,
          borderWidth: 2,
        },
        {
          label: 'Coût locataire',
          data: data.map((y) => y.currentMonthlyTotal),
          borderColor: COLORS.rent.border,
          backgroundColor: COLORS.rent.bg,
          fill: true,
          tension: 0.3,
          pointRadius: 2,
          pointHitRadius: 10,
          borderWidth: 2,
          borderDash: [5, 3],
        },
      ],
    }),
    [data, labels]
  );

  const options: ChartOptions<'line'> = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      tooltip: {
        ...defaultTooltipOptions,
        callbacks: {
          label: (ctx) => `${ctx.dataset.label}: ${formatCurrency(ctx.parsed.y ?? 0)}/mois`,
        },
      },
      legend: defaultLegendOptions,
    },
    scales: {
      x: {
        grid: { display: false },
        ticks: { color: '#94a3b8', font: { size: 10 } },
      },
      y: {
        grid: { color: 'rgba(148, 163, 184, 0.1)' },
        ticks: {
          color: '#94a3b8',
          font: { size: 10 },
          callback: (v) => formatCurrencyShort(v as number),
        },
      },
    },
  };

  return (
    <div className="h-72">
      <Line data={chartData} options={options} />
    </div>
  );
}

function ResaleChart({ data, labels }: ChartProps) {
  const chartData = useMemo(
    () => ({
      labels,
      datasets: [
        {
          label: 'Plus/moins-value nette',
          data: data.map((y) => y.netResale),
          borderColor: data.map((y) =>
            y.netResale >= 0 ? COLORS.resale.border : COLORS.negative.border
          ),
          backgroundColor: data.map((y) =>
            y.netResale >= 0 ? COLORS.resale.bg : COLORS.negative.bg
          ),
          borderWidth: 2,
          borderRadius: 3,
        },
      ],
    }),
    [data, labels]
  );

  const options: ChartOptions<'bar'> = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      tooltip: {
        ...defaultTooltipOptions,
        callbacks: {
          label: (ctx) => `Plus/moins-value: ${formatCurrency(ctx.parsed.y ?? 0)}`,
        },
      },
      legend: { display: false },
    },
    scales: {
      x: {
        grid: { display: false },
        ticks: { color: '#94a3b8', font: { size: 10 } },
      },
      y: {
        grid: { color: 'rgba(148, 163, 184, 0.1)' },
        ticks: {
          color: '#94a3b8',
          font: { size: 10 },
          callback: (v) => formatCurrencyShort(v as number),
        },
      },
    },
  };

  return (
    <div className="h-72">
      <Bar data={chartData} options={options} />
    </div>
  );
}

function CostDonut() {
  const { results } = useSimulation();

  const chartData = useMemo(
    () => ({
      labels: ['Capital', 'Intérêts', 'Assurance'],
      datasets: [
        {
          data: [results.totalCapital, results.totalInterest, results.totalInsurance],
          backgroundColor: [
            COLORS.capital.border,
            COLORS.interest.border,
            COLORS.insurance.border,
          ],
          borderWidth: 0,
          hoverOffset: 8,
        },
      ],
    }),
    [results]
  );

  const options: ChartOptions<'doughnut'> = {
    responsive: true,
    maintainAspectRatio: true,
    cutout: '65%',
    plugins: {
      tooltip: {
        ...defaultTooltipOptions,
        callbacks: {
          label: (ctx) => {
            const total = results.grandTotal;
            const pct = total > 0 ? ((ctx.parsed / total) * 100).toFixed(1) : 0;
            return `${ctx.label}: ${formatCurrency(ctx.parsed)} (${pct}%)`;
          },
        },
      },
      legend: defaultLegendOptions,
    },
  };

  return (
    <div className="relative">
      <Doughnut data={chartData} options={options} />
      <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
        <div className="text-center">
          <div className="text-lg font-bold text-slate-900 dark:text-slate-100 tabular-nums">
            {formatCurrency(results.grandTotal)}
          </div>
          <div className="text-xs text-slate-400 dark:text-slate-500">Coût total</div>
        </div>
      </div>
    </div>
  );
}

// ─── Chart Card Wrapper ─────────────────────────────────────────────────────

function ChartCard({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div className="card">
      <div className="px-5 py-4 border-b border-slate-100 dark:border-slate-800">
        <h3 className="text-sm font-semibold text-slate-700 dark:text-slate-200">{title}</h3>
      </div>
      <div className="p-5">{children}</div>
    </div>
  );
}

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

interface ChartProps {
  data: ReturnType<typeof useSimulation>['results']['yearlySummaries'];
  labels: string[];
}
