import { Card, Title, Text, Group, Badge, Tooltip } from '@mantine/core';
import { useMemo } from 'react';

const fmt = (v: number) => v.toLocaleString('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });

const typeColors: Record<string, string> = {
  cd: '#228be6',
  money_market: '#40c057',
  treasury: '#7950f2',
  savings: '#fd7e14',
  other: '#868e96',
};

interface Props {
  investments: any[];
  /** Optional shared time range to align with ProjectionChart */
  sharedStartDate?: Date;
  sharedEndDate?: Date;
}

export function InvestmentTimeline({ investments, sharedStartDate, sharedEndDate }: Props) {
  const { items, startDate, endDate, totalMonths } = useMemo(() => {
    const now = new Date();
    const items = investments
      .filter((inv: any) => inv.purchase_date || inv.maturity_date)
      .map((inv: any) => ({
        ...inv,
        start: inv.purchase_date ? new Date(inv.purchase_date) : now,
        end: inv.maturity_date ? new Date(inv.maturity_date) : null,
      }));

    if (!items.length) return { items: [], startDate: now, endDate: now, totalMonths: 1 };

    // Use shared range if provided (to align with ProjectionChart), otherwise compute from investments
    let startDate: Date;
    let endDate: Date;
    if (sharedStartDate && sharedEndDate) {
      startDate = sharedStartDate;
      endDate = sharedEndDate;
    } else {
      const allDates = items.flatMap((i: any) => [i.start, i.end].filter(Boolean)) as Date[];
      startDate = new Date(Math.min(...allDates.map((d) => d.getTime())));
      endDate = new Date(Math.max(...allDates.map((d) => d.getTime())));
    }
    const totalMonths = Math.max(
      (endDate.getFullYear() - startDate.getFullYear()) * 12 + (endDate.getMonth() - startDate.getMonth()) + 1,
      1,
    );

    return { items, startDate, endDate, totalMonths };
  }, [investments, sharedStartDate, sharedEndDate]);

  if (!items.length) return null;

  const getPercent = (date: Date) => {
    const months = (date.getFullYear() - startDate.getFullYear()) * 12 + (date.getMonth() - startDate.getMonth());
    return Math.max(0, Math.min(100, (months / totalMonths) * 100));
  };

  // Generate year labels
  const yearLabels: { year: number; percent: number }[] = [];
  for (let y = startDate.getFullYear(); y <= endDate.getFullYear(); y++) {
    const janDate = new Date(y, 0, 1);
    if (janDate >= startDate && janDate <= endDate) {
      yearLabels.push({ year: y, percent: getPercent(janDate) });
    }
  }

  return (
    <Card withBorder p="lg">
      <Title order={4} mb="md">Investment Timeline</Title>

      {/* Year markers */}
      <div style={{ position: 'relative', height: 20, marginBottom: 8 }}>
        {yearLabels.map((yl) => (
          <Text
            key={yl.year}
            size="xs"
            c="dimmed"
            fw={700}
            style={{ position: 'absolute', left: `${yl.percent}%`, transform: 'translateX(-50%)' }}
          >
            {yl.year}
          </Text>
        ))}
      </div>

      {/* Timeline bars */}
      <div style={{ position: 'relative', minHeight: items.length * 40 + 10 }}>
        {/* Background grid */}
        <div style={{
          position: 'absolute', inset: 0, borderLeft: '1px solid var(--mantine-color-gray-3)',
          borderRight: '1px solid var(--mantine-color-gray-3)',
        }}>
          {yearLabels.map((yl) => (
            <div
              key={yl.year}
              style={{
                position: 'absolute', left: `${yl.percent}%`, top: 0, bottom: 0,
                borderLeft: '1px dashed var(--mantine-color-gray-3)',
              }}
            />
          ))}
        </div>

        {items.map((inv: any, idx: number) => {
          const leftPct = getPercent(inv.start);
          const rightPct = inv.end ? getPercent(inv.end) : leftPct + 2;
          const widthPct = Math.max(rightPct - leftPct, 1);
          const color = typeColors[inv.investment_type] || '#868e96';

          return (
            <Tooltip
              key={inv.id}
              label={
                <div>
                  <Text size="xs" fw={600}>{inv.label}</Text>
                  <Text size="xs">{fmt(parseFloat(inv.principal))} @ {parseFloat(inv.interest_rate || 0).toFixed(2)}%</Text>
                  {inv.purchase_date && <Text size="xs">Start: {new Date(inv.purchase_date).toLocaleDateString()}</Text>}
                  {inv.maturity_date && <Text size="xs">Maturity: {new Date(inv.maturity_date).toLocaleDateString()}</Text>}
                </div>
              }
              position="top"
              multiline
              withArrow
            >
              <div
                style={{
                  position: 'absolute',
                  left: `${leftPct}%`,
                  width: `${widthPct}%`,
                  top: idx * 40 + 4,
                  height: 28,
                  borderRadius: 4,
                  background: color,
                  opacity: inv.executed_investment_id ? 0.5 : 0.85,
                  display: 'flex',
                  alignItems: 'center',
                  paddingLeft: 8,
                  paddingRight: 8,
                  cursor: 'pointer',
                  minWidth: 60,
                }}
              >
                <Text size="xs" c="white" fw={600} truncate style={{ lineHeight: 1 }}>
                  {inv.label} — {fmt(parseFloat(inv.principal))}
                </Text>
              </div>
            </Tooltip>
          );
        })}
      </div>

      {/* Legend */}
      <Group gap="md" mt="md">
        {Object.entries(typeColors).map(([type, color]) => (
          <Group key={type} gap={4}>
            <div style={{ width: 12, height: 12, borderRadius: 2, background: color }} />
            <Text size="xs" c="dimmed">{type.replace('_', ' ')}</Text>
          </Group>
        ))}
      </Group>
    </Card>
  );
}
