'use client';

import { format } from 'date-fns';
import { Panel } from '@/components/ui/panel';
import { formatCurrency } from '@/lib/format';
import { InteractivePriceChart } from '@/components/charts/interactive-price-chart';
import type { DataSeries, Holding, PriceData } from '@/lib/types';

type PriceHistoryCardProps = {
  loading: boolean;
  priceHistory: PriceData<Array<{ date: string; close: number }> | null>;
  benchmarkHistory: PriceData<Array<{ date: string; close: number }> | null>;
  quote: PriceData<number | null>;
  position: Holding | null;
};

function formatLongDate(value: string) {
  const parsed = new Date(value);
  return Number.isNaN(parsed.getTime()) ? value : format(parsed, 'MMM dd, yyyy');
}

function asFiniteNumber(value: string | number | null | undefined) {
  if (value === null || value === undefined) {
    return null;
  }

  const parsed = typeof value === 'number' ? value : Number(value);
  return Number.isFinite(parsed) ? parsed : null;
}

export function PriceHistoryCard(props: PriceHistoryCardProps) {
  const priceHistoryValue = props.priceHistory.value;
  const benchmarkHistoryValue = props.benchmarkHistory.value;
  const quoteValue = props.quote.value;

  const firstPoint = priceHistoryValue?.[0];
  const lastPoint = priceHistoryValue?.[priceHistoryValue.length - 1];
  const inPortfolio = props.position !== null;
  const hasPriceData = priceHistoryValue !== null && priceHistoryValue.length > 0;

  const defaultChange = firstPoint && lastPoint ? lastPoint.close - firstPoint.close : null;
  const defaultChangePct = firstPoint && firstPoint.close > 0 && defaultChange !== null
    ? (defaultChange / firstPoint.close) * 100
    : null;
  const holdingChange = asFiniteNumber(props.position?.gain_loss);
  const holdingChangePct = asFiniteNumber(props.position?.gain_loss_pct);

  const change = inPortfolio ? holdingChange : defaultChange;
  const changePct = inPortfolio ? holdingChangePct : defaultChangePct;
  const rangeLabel = inPortfolio ? 'Holding return' : '1Y return';
  const changeLabel = inPortfolio ? 'Holding P/L' : '1Y change';
  const dateRange = inPortfolio
    ? props.position?.created_at && (props.position.last_price_at ?? lastPoint?.date)
      ? `${formatLongDate(props.position.created_at)} to ${formatLongDate(props.position.last_price_at ?? lastPoint?.date ?? '')}`
      : 'No holding period available'
    : firstPoint && lastPoint
      ? `${formatLongDate(firstPoint.date)} to ${formatLongDate(lastPoint.date)}`
      : 'No comparison range';
  const statusToneClass = inPortfolio ? 'text-[#96f5bf]' : 'text-[color:var(--terminal-bright)]';
  const performanceToneClass = change !== null && change < 0 ? 'text-[#ff9f9f]' : 'text-[#96f5bf]';

  const chartData = priceHistoryValue?.map(point => ({
    date: point.date,
    price: point.close
  })) ?? [];

  const benchmarkData = benchmarkHistoryValue?.map((point) => ({
    date: point.date,
    price: point.close
  })) ?? [];

  const comparisonSeries: DataSeries[] = [
    {
      id: 'stock',
      label: 'Stock',
      data: chartData,
      color: '#96f5bf',
      type: 'line'
    },
    {
      id: 'sp500',
      label: 'S&P 500',
      data: benchmarkData,
      color: '#8ba0b8',
      type: 'line'
    }
  ];

  const quoteAvailable = quoteValue !== null && Number.isFinite(quoteValue);
  const staleIndicator = props.quote.stale ? ' (stale)' : '';
  const helperText = quoteAvailable
    ? `Spot price ${formatCurrency(quoteValue)}${staleIndicator}`
    : 'Spot price unavailable';

  return (
    <Panel title="Price chart" subtitle={hasPriceData ? 'Interactive chart with historical data' : 'Price data unavailable'}>
      <div className="space-y-4">
        {!hasPriceData && (
          <div className="rounded border border-[color:var(--line-weak)] bg-[color:var(--surface-dim)] px-4 py-3">
            <p className="text-sm text-[color:var(--terminal-muted)]">
              Price history data is currently unavailable. This may be due to a temporary issue with the market data provider.
            </p>
          </div>
        )}
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
          <div className="border-b border-[color:var(--line-weak)] px-4 py-4 sm:border-b-0 sm:border-r">
            <p className="text-xs uppercase tracking-[0.14em] text-[color:var(--terminal-muted)]">Portfolio status</p>
            <p className={`mt-2 text-2xl font-semibold ${statusToneClass}`}>{inPortfolio ? 'In portfolio' : 'Not in portfolio'}</p>
            <p className="mt-2 text-xs text-[color:var(--terminal-muted)]">{helperText}</p>
          </div>
          <div className="border-b border-[color:var(--line-weak)] px-4 py-4 sm:border-b-0 sm:border-r">
            <p className="text-xs uppercase tracking-[0.14em] text-[color:var(--terminal-muted)]">{changeLabel}</p>
            <p className={`mt-2 text-2xl font-semibold ${performanceToneClass}`}>
              {change === null ? 'n/a' : formatCurrency(change)}
            </p>
          </div>
          <div className="px-4 py-4">
            <p className="text-xs uppercase tracking-[0.14em] text-[color:var(--terminal-muted)]">{rangeLabel}</p>
            <p className={`mt-2 text-2xl font-semibold ${performanceToneClass}`}>
              {changePct === null ? 'n/a' : `${changePct.toFixed(2)}%`}
            </p>
            <p className="mt-2 text-xs text-[color:var(--terminal-muted)]">
              {dateRange}
            </p>
          </div>
        </div>

        {hasPriceData && (
          <InteractivePriceChart
            data={chartData}
            dataSeries={comparisonSeries}
            defaultChartType="line"
            defaultTimeRange="1Y"
            showVolume={false}
            showToolbar={true}
            height={320}
            loading={props.loading}
            formatters={{
              price: formatCurrency,
              date: (date: string) => format(new Date(date), 'MMM dd, yyyy')
            }}
          />
        )}
      </div>
    </Panel>
  );
}
