import { useParams, useNavigate, Link } from '@tanstack/react-router';
import { useState, useEffect } from 'react';
import {
  useCompany,
  useCompanySources,
  useCreateAlias,
  useCreateSource,
  useCompanyMacroImpacts,
  useCompanyCompetitors,
  useInferCompetitors,
  useHistoricalPatterns,
  useCompetitiveSignals,
  useCorporateDecisions,
  useTrends,
  useTrendHistory,
  useMarketPrices,
  useDocument,
  usePositions,
} from '../api/hooks';
import { StatusBadge, ConfidenceBar, LoadingSpinner, Card } from '../components/ui';
import { DataTable, type Column } from '../components/DataTable';
import type { Source, Alias, MacroImpactRecord, CompetitorRelationship, HistoricalPattern, CompetitiveSignal, CorporateDecision, TrendSummary, MarketPrice } from '../api/hooks';
import {
  LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer,
  CartesianGrid, Legend, ReferenceLine,
} from 'recharts';

const sourceCols: Column<Source>[] = [
  { key: 'source_type', header: 'Type' },
  { key: 'source_name', header: 'Name' },
  { key: 'credibility_score', header: 'Credibility', render: (r) => <span>{(r.credibility_score * 100).toFixed(0)}%</span> },
  { key: 'active', header: 'Status', render: (r) => <StatusBadge status={r.active ? 'active' : 'disabled'} /> },
];

export function CompanyDetailPage() {
  const { id } = useParams({ from: '/companies/$id' });
  const navigate = useNavigate();
  const { data: company, isLoading } = useCompany(id);
  const { data: sources } = useCompanySources(id);
  const { data: macroData } = useCompanyMacroImpacts(company?.ticker);
  const { data: competitors } = useCompanyCompetitors(id);
  const inferCompetitors = useInferCompetitors(id);
  const { data: patterns } = useHistoricalPatterns(company?.ticker);
  const { data: signals } = useCompetitiveSignals(company?.ticker);
  const { data: decisions } = useCorporateDecisions(company?.ticker);
  const { data: trends } = useTrends({ ticker: company?.ticker, limit: 200 });
  const [selectedWindow, setSelectedWindow] = useState('7d');
  const { data: trendHistory } = useTrendHistory({ ticker: company?.ticker, window: selectedWindow, limit: 500 });
  const { data: marketPriceData } = useMarketPrices(company?.ticker, 200);
  const marketPrices = marketPriceData?.bars ?? [];
  const range90d = marketPriceData?.range_90d ?? { low: null, high: null };
  const { data: positions } = usePositions(company?.ticker);
  const [tab, setTab] = useState<'trends' | 'sources' | 'aliases' | 'macro' | 'competitors' | 'patterns' | 'signals' | 'decisions'>('trends');

  if (isLoading || !company) return <LoadingSpinner />;

  const tabs = ['trends', 'sources', 'aliases', 'macro', 'competitors', 'patterns', 'signals', 'decisions'] as const;

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-3">
        <h1 className="text-xl font-semibold text-gray-100">{company.ticker}</h1>
        <StatusBadge status={company.active ? 'active' : 'disabled'} />
      </div>

      <Card>
        <dl className="grid grid-cols-2 gap-x-8 gap-y-2 text-sm sm:grid-cols-4">
          <div><dt className="text-gray-500">Name</dt><dd className="text-gray-200">{company.legal_name}</dd></div>
          <div><dt className="text-gray-500">Exchange</dt><dd className="text-gray-200">{company.exchange ?? '—'}</dd></div>
          <div><dt className="text-gray-500">Sector</dt><dd className="text-gray-200">{company.sector ?? '—'}</dd></div>
          <div><dt className="text-gray-500">Industry</dt><dd className="text-gray-200">{company.industry ?? '—'}</dd></div>
          <div><dt className="text-gray-500">Market Cap</dt><dd className="text-gray-200">{company.market_cap_bucket ?? '—'}</dd></div>
          <div><dt className="text-gray-500">Sources</dt><dd className="text-gray-200">{company.active_source_count ?? 0}</dd></div>
        </dl>
      </Card>

      {/* Tabs */}
      <div className="flex gap-4 border-b border-surface-700 overflow-x-auto">
        {tabs.map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`whitespace-nowrap pb-2 text-sm font-medium capitalize transition-colors ${tab === t ? 'border-b-2 border-brand-500 text-brand-300' : 'text-gray-500 hover:text-gray-300'}`}
          >
            {t}
          </button>
        ))}
      </div>

      {tab === 'trends' && (
        <div className="space-y-4">
          <PositionCard positions={positions ?? []} ticker={company.ticker} />
          <TrendHistoryChart trends={trendHistory ?? []} latestTrends={trends ?? []} ticker={company.ticker} marketPrices={marketPrices} range90d={range90d} selectedWindow={selectedWindow} onWindowChange={setSelectedWindow} />
        </div>
      )}

      {tab === 'sources' && (
        <div className="space-y-4">
          <DataTable<Source> data={sources ?? []} columns={sourceCols} keyField="id" />
          <AddSourceForm companyId={id} />
        </div>
      )}

      {tab === 'aliases' && (
        <div className="space-y-4">
          <AliasesList aliases={company.aliases ?? []} />
          <AddAliasForm companyId={id} />
        </div>
      )}

      {tab === 'macro' && (
        <MacroExposurePanel macroData={macroData} onEventClick={(eventId) => navigate({ to: '/macro/events/$id', params: { id: eventId } })} />
      )}

      {tab === 'competitors' && (
        <CompetitorsPanel competitors={competitors ?? []} onInfer={() => inferCompetitors.mutate()} isInferring={inferCompetitors.isPending} />
      )}

      {tab === 'patterns' && (
        <HistoricalPatternsPanel patterns={patterns ?? []} />
      )}

      {tab === 'signals' && (
        <CompetitiveSignalsPanel signals={signals ?? []} />
      )}

      {tab === 'decisions' && (
        <DecisionsPanel decisions={decisions ?? []} />
      )}
    </div>
  );
}

function AliasesList({ aliases }: { aliases: Alias[] }) {
  if (aliases.length === 0) return <p className="text-sm text-gray-500">No aliases configured</p>;
  return (
    <div className="flex flex-wrap gap-2">
      {aliases.map((a) => (
        <span key={a.id} className="rounded-full border border-surface-700 bg-surface-800 px-3 py-1 text-xs text-gray-300">
          {a.alias} <span className="text-gray-500">({a.alias_type})</span>
        </span>
      ))}
    </div>
  );
}

function AddAliasForm({ companyId }: { companyId: string }) {
  const [alias, setAlias] = useState('');
  const mutation = useCreateAlias(companyId);

  return (
    <form
      className="flex gap-2"
      onSubmit={(e) => {
        e.preventDefault();
        if (alias.trim()) mutation.mutate({ alias: alias.trim() }, { onSuccess: () => setAlias('') });
      }}
    >
      <input
        type="text"
        placeholder="Add alias…"
        value={alias}
        onChange={(e) => setAlias(e.target.value)}
        className="rounded-md border border-surface-700 bg-surface-900 px-3 py-1.5 text-sm text-gray-200 placeholder-gray-500 focus:border-brand-500 focus:outline-none"
        aria-label="New alias"
      />
      <button type="submit" disabled={mutation.isPending} className="rounded-md bg-brand-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50">
        Add
      </button>
    </form>
  );
}

function AddSourceForm({ companyId }: { companyId: string }) {
  const [open, setOpen] = useState(false);
  const [sourceType, setSourceType] = useState('market_api');
  const [sourceName, setSourceName] = useState('');
  const [credibility, setCredibility] = useState(0.5);
  const mutation = useCreateSource(companyId);

  if (!open) {
    return (
      <button onClick={() => setOpen(true)} className="rounded-md bg-brand-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-700">
        Add Source
      </button>
    );
  }

  return (
    <Card>
      <form
        className="space-y-3"
        onSubmit={(e) => {
          e.preventDefault();
          mutation.mutate(
            { source_type: sourceType, source_name: sourceName, credibility_score: credibility },
            { onSuccess: () => { setOpen(false); setSourceName(''); } },
          );
        }}
      >
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="mb-1 block text-xs text-gray-500" htmlFor="source-type">Type</label>
            <select
              id="source-type"
              value={sourceType}
              onChange={(e) => setSourceType(e.target.value)}
              className="w-full rounded-md border border-surface-700 bg-surface-900 px-2 py-1.5 text-sm text-gray-200"
            >
              {['market_api', 'news_api', 'filings_api', 'web_scrape', 'broker'].map((t) => (
                <option key={t} value={t}>{t}</option>
              ))}
            </select>
          </div>
          <div>
            <label className="mb-1 block text-xs text-gray-500" htmlFor="source-name">Name</label>
            <input
              id="source-name"
              type="text"
              value={sourceName}
              onChange={(e) => setSourceName(e.target.value)}
              className="w-full rounded-md border border-surface-700 bg-surface-900 px-2 py-1.5 text-sm text-gray-200 placeholder-gray-500"
              placeholder="Source name"
              required
            />
          </div>
        </div>
        <div>
          <label className="mb-1 block text-xs text-gray-500" htmlFor="credibility">Credibility: {(credibility * 100).toFixed(0)}%</label>
          <input
            id="credibility"
            type="range"
            min={0}
            max={1}
            step={0.05}
            value={credibility}
            onChange={(e) => setCredibility(Number(e.target.value))}
            className="w-full"
          />
        </div>
        <div className="flex gap-2">
          <button type="submit" disabled={mutation.isPending} className="rounded-md bg-brand-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50">
            Save
          </button>
          <button type="button" onClick={() => setOpen(false)} className="rounded-md border border-surface-700 px-3 py-1.5 text-sm text-gray-400 hover:bg-surface-800">
            Cancel
          </button>
        </div>
      </form>
    </Card>
  );
}

function MacroExposurePanel({ macroData, onEventClick }: {
  macroData: { exposure_profile: import('../api/hooks').ExposureProfile | null; impacts: MacroImpactRecord[] } | undefined;
  onEventClick: (eventId: string) => void;
}) {
  if (!macroData) return <p className="text-sm text-gray-500">Loading macro data…</p>;

  const profile = macroData.exposure_profile;
  const impacts = macroData.impacts ?? [];

  return (
    <div className="space-y-4">
      {/* Exposure Profile */}
      <Card>
        <h2 className="mb-3 text-sm font-medium text-gray-400">Exposure Profile</h2>
        {!profile ? (
          <p className="text-sm text-gray-500">No exposure profile configured</p>
        ) : (
          <dl className="grid grid-cols-2 gap-x-8 gap-y-2 text-sm sm:grid-cols-3">
            <div>
              <dt className="text-gray-500">Market Position</dt>
              <dd><StatusBadge status={profile.market_position_tier} /></dd>
            </div>
            <div>
              <dt className="text-gray-500">Export Dependency</dt>
              <dd className="text-gray-200">{(profile.export_dependency_pct * 100).toFixed(0)}%</dd>
            </div>
            <div>
              <dt className="text-gray-500">Source</dt>
              <dd><StatusBadge status={profile.source} /></dd>
            </div>
            <div>
              <dt className="text-gray-500">Confidence</dt>
              <dd><ConfidenceBar value={profile.confidence} /></dd>
            </div>
            <div>
              <dt className="text-gray-500">Revenue Mix</dt>
              <dd className="flex flex-wrap gap-1 mt-1">
                {Object.entries(profile.geographic_revenue_mix).map(([region, pct]) => (
                  <span key={region} className="rounded bg-surface-800 px-1.5 py-0.5 text-[10px] text-gray-300">
                    {region}: {(pct * 100).toFixed(0)}%
                  </span>
                ))}
              </dd>
            </div>
            <div>
              <dt className="text-gray-500">Supply Chain Regions</dt>
              <dd className="flex flex-wrap gap-1 mt-1">
                {profile.supply_chain_regions.map((r) => (
                  <span key={r} className="rounded bg-surface-800 px-1.5 py-0.5 text-[10px] text-gray-300">{r}</span>
                ))}
              </dd>
            </div>
            <div>
              <dt className="text-gray-500">Key Commodities</dt>
              <dd className="flex flex-wrap gap-1 mt-1">
                {profile.key_input_commodities.length > 0
                  ? profile.key_input_commodities.map((c) => (
                      <span key={c} className="rounded bg-surface-800 px-1.5 py-0.5 text-[10px] text-gray-300">{c}</span>
                    ))
                  : <span className="text-gray-500">—</span>}
              </dd>
            </div>
          </dl>
        )}
      </Card>

      {/* Active Macro Impacts */}
      <Card>
        <h2 className="mb-3 text-sm font-medium text-gray-400">Active Macro Impacts ({impacts.length})</h2>
        {impacts.length === 0 ? (
          <p className="text-sm text-gray-500">No active macro impacts</p>
        ) : (
          <div className="space-y-2">
            {impacts.map((impact) => (
              <div
                key={impact.id}
                className="flex items-center justify-between rounded-lg border border-surface-700 bg-surface-950 p-3 cursor-pointer hover:border-brand-500/50"
                onClick={() => onEventClick(impact.event_id)}
              >
                <div className="flex items-center gap-3">
                  <StatusBadge status={impact.impact_direction} />
                  <ConfidenceBar value={impact.macro_impact_score} />
                  <div className="flex flex-wrap gap-1">
                    {impact.contributing_factors.map((f, i) => (
                      <span key={i} className="rounded bg-surface-800 px-1.5 py-0.5 text-[10px] text-gray-400">{f}</span>
                    ))}
                  </div>
                </div>
                <span className="text-xs text-gray-500">{new Date(impact.computed_at).toLocaleDateString()}</span>
              </div>
            ))}
          </div>
        )}
      </Card>
    </div>
  );
}

function CompetitorsPanel({ competitors, onInfer, isInferring }: {
  competitors: CompetitorRelationship[];
  onInfer: () => void;
  isInferring: boolean;
}) {
  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-sm font-medium text-gray-400">Active Competitors ({competitors.length})</h2>
        <button
          onClick={onInfer}
          disabled={isInferring}
          className="rounded-md bg-brand-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50"
        >
          {isInferring ? 'Inferring…' : 'Infer Competitors'}
        </button>
      </div>
      {competitors.length === 0 ? (
        <p className="text-sm text-gray-500">No competitor relationships defined</p>
      ) : (
        <div className="space-y-2">
          {competitors.map((c) => (
            <div key={c.id} className="flex items-center justify-between rounded-lg border border-surface-700 bg-surface-950 p-3">
              <div className="flex items-center gap-3">
                <span className="font-mono font-semibold text-brand-300">{c.ticker ?? c.legal_name ?? 'Unknown'}</span>
                <StatusBadge status={c.relationship_type} />
                <ConfidenceBar value={c.strength} />
              </div>
              <div className="flex items-center gap-2">
                <span className={`rounded px-1.5 py-0.5 text-[10px] font-medium ${c.source === 'manual' ? 'bg-blue-900/40 border border-blue-700/50 text-blue-400' : 'bg-emerald-900/40 border border-emerald-700/50 text-emerald-400'}`}>
                  {c.source.toUpperCase()}
                </span>
                {c.bidirectional && (
                  <span className="rounded bg-surface-800 px-1.5 py-0.5 text-[10px] text-gray-400">↔ bidirectional</span>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function HistoricalPatternsPanel({ patterns }: { patterns: HistoricalPattern[] }) {
  return (
    <div className="space-y-4">
      <h2 className="text-sm font-medium text-gray-400">Historical Patterns ({patterns.length})</h2>
      {patterns.length === 0 ? (
        <p className="text-sm text-gray-500">No historical patterns found</p>
      ) : (
        <div className="space-y-2">
          {patterns.map((p, i) => (
            <Card key={i}>
              <div className="flex items-center justify-between mb-2">
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-gray-200">{p.catalyst_type}</span>
                  <span className="rounded bg-surface-800 px-2 py-0.5 text-xs text-gray-400">{p.time_horizon}</span>
                  <span className={`rounded px-1.5 py-0.5 text-[10px] font-medium ${p.tier === 'major_corporate_decision' ? 'bg-orange-900/40 border border-orange-700/50 text-orange-400' : 'bg-surface-800 text-gray-400'}`}>
                    {p.tier === 'major_corporate_decision' ? 'MAJOR' : 'ROUTINE'}
                  </span>
                  {p.insufficient_data && (
                    <span className="rounded bg-yellow-900/40 border border-yellow-700/50 px-1.5 py-0.5 text-[10px] font-medium text-yellow-400">LOW DATA</span>
                  )}
                </div>
                <ConfidenceBar value={p.pattern_confidence} />
              </div>
              <div className="grid grid-cols-2 gap-x-6 gap-y-1 text-xs sm:grid-cols-4">
                <div>
                  <span className="text-gray-500">Samples: </span>
                  <span className="text-gray-300">{p.sample_count}</span>
                </div>
                <div>
                  <span className="text-gray-500">Bullish: </span>
                  <span className="text-green-400">{(p.bullish_pct * 100).toFixed(0)}%</span>
                </div>
                <div>
                  <span className="text-gray-500">Bearish: </span>
                  <span className="text-red-400">{(p.bearish_pct * 100).toFixed(0)}%</span>
                </div>
                <div>
                  <span className="text-gray-500">Avg Strength: </span>
                  <span className="text-gray-300">{(p.avg_strength * 100).toFixed(0)}%</span>
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}

function CompetitiveSignalsPanel({ signals }: { signals: CompetitiveSignal[] }) {
  const [expandedId, setExpandedId] = useState<string | null>(null);

  return (
    <div className="space-y-4">
      <h2 className="text-sm font-medium text-gray-400">Incoming Competitive Signals ({signals.length})</h2>
      {signals.length === 0 ? (
        <p className="text-sm text-gray-500">No competitive signals received</p>
      ) : (
        <div className="space-y-2">
          {signals.map((s) => (
            <SignalRow key={s.id} signal={s} expanded={expandedId === s.id} onToggle={() => setExpandedId(expandedId === s.id ? null : s.id)} />
          ))}
        </div>
      )}
    </div>
  );
}

function SignalRow({ signal: s, expanded, onToggle }: { signal: CompetitiveSignal; expanded: boolean; onToggle: () => void }) {
  const { data: doc } = useDocument(s.source_document_id);
  const docLabel = doc?.title ?? `doc:${s.source_document_id.slice(0, 8)}…`;

  return (
    <div>
      <div
        className="flex items-center justify-between rounded-lg border border-cyan-700/30 bg-cyan-900/10 p-3 cursor-pointer hover:border-cyan-500/50"
        onClick={onToggle}
      >
        <div className="flex items-center gap-3">
          <span className="rounded bg-cyan-900/40 border border-cyan-700/50 px-1.5 py-0.5 text-[10px] font-medium text-cyan-400">COMPETITIVE</span>
          <span className="font-mono text-sm text-brand-300">{s.source_ticker}</span>
          <span className="text-xs text-gray-400">→</span>
          <StatusBadge status={s.catalyst_type} />
          <StatusBadge status={s.signal_direction} />
        </div>
        <div className="flex items-center gap-3">
          <Link
            to="/documents/$id"
            params={{ id: s.source_document_id }}
            className="max-w-[180px] truncate text-xs text-brand-400 hover:underline"
            onClick={(e) => e.stopPropagation()}
            title={doc?.title ?? s.source_document_id}
          >
            {docLabel}
          </Link>
          <ConfidenceBar value={s.signal_strength} />
          <span className="text-xs text-gray-500">{new Date(s.computed_at).toLocaleDateString()}</span>
        </div>
      </div>
      {expanded && (
        <Card className="mt-1 ml-4">
          <dl className="grid grid-cols-2 gap-x-6 gap-y-2 text-xs sm:grid-cols-3">
            <div>
              <dt className="text-gray-500">Source Ticker</dt>
              <dd className="font-mono text-gray-200">{s.source_ticker}</dd>
            </div>
            <div>
              <dt className="text-gray-500">Target Ticker</dt>
              <dd className="font-mono text-gray-200">{s.target_ticker}</dd>
            </div>
            <div>
              <dt className="text-gray-500">Catalyst Type</dt>
              <dd className="text-gray-200">{s.catalyst_type}</dd>
            </div>
            <div>
              <dt className="text-gray-500">Pattern Confidence</dt>
              <dd><ConfidenceBar value={s.pattern_confidence} /></dd>
            </div>
            <div>
              <dt className="text-gray-500">Signal Strength</dt>
              <dd><ConfidenceBar value={s.signal_strength} /></dd>
            </div>
            <div>
              <dt className="text-gray-500">Relationship Strength</dt>
              <dd><ConfidenceBar value={s.relationship_strength} /></dd>
            </div>
            <div>
              <dt className="text-gray-500">Source Document</dt>
              <dd>
                <Link
                  to="/documents/$id"
                  params={{ id: s.source_document_id }}
                  className="text-brand-400 hover:underline"
                  onClick={(e) => e.stopPropagation()}
                >
                  {docLabel}
                </Link>
              </dd>
            </div>
            <div>
              <dt className="text-gray-500">Computed At</dt>
              <dd className="text-gray-200">{new Date(s.computed_at).toLocaleString()}</dd>
            </div>
          </dl>
        </Card>
      )}
    </div>
  );
}

function DecisionsPanel({ decisions }: { decisions: CorporateDecision[] }) {
  return (
    <div className="space-y-4">
      <h2 className="text-sm font-medium text-gray-400">Corporate Decision Timeline ({decisions.length})</h2>
      {decisions.length === 0 ? (
        <p className="text-sm text-gray-500">No major corporate decisions found</p>
      ) : (
        <div className="space-y-2">
          {decisions.map((d, i) => (
            <div key={i} className="flex items-start gap-4 rounded-lg border border-surface-700 bg-surface-950 p-3">
              <div className="flex flex-col items-center">
                <span className="text-xs font-medium text-gray-400">{new Date(d.date).toLocaleDateString()}</span>
                <div className="mt-1 h-full w-px bg-surface-700" />
              </div>
              <div className="flex-1 space-y-1">
                <div className="flex items-center gap-2">
                  <span className="rounded bg-orange-900/40 border border-orange-700/50 px-1.5 py-0.5 text-[10px] font-medium text-orange-400">
                    {d.catalyst_type}
                  </span>
                  <StatusBadge status={d.trend_direction} />
                  <ConfidenceBar value={d.trend_strength} />
                </div>
                <p className="text-sm text-gray-300">{d.summary}</p>
                <div className="flex gap-4 text-xs text-gray-500">
                  <span>Samples: {d.sample_count}</span>
                  <span>Confidence: {(d.pattern_confidence * 100).toFixed(0)}%</span>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Trend History Chart
// ---------------------------------------------------------------------------

const DIRECTION_VALUE: Record<string, number> = {
  bullish: 1,
  bearish: -1,
  mixed: 0,
  neutral: 0,
};

const WINDOW_ORDER = ['intraday', '1d', '7d', '30d', '90d'];

interface ChartPoint {
  time: string;
  timestamp: number;
  strength: number;
  confidence: number;
  contradiction: number;
  direction: number;
  directionLabel: string;
  window: string;
  price?: number;
}

function ChartXTick({ x, y, payload }: { x?: number; y?: number; payload?: { value: number } }) {
  if (!payload || !x || !y) return null;
  const d = new Date(payload.value);
  const dateStr = d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
  const timeStr = d.toLocaleTimeString('en-US', { hour: 'numeric', hour12: true });

  return (
    <g transform={`translate(${x},${y + 4})`}>
      <text x={0} y={0} textAnchor="end" fontSize={10} transform="rotate(-35)">
        <tspan fill="#e2e8f0" fontWeight="bold">{dateStr} </tspan>
        <tspan fill="#94a3b8">{timeStr}</tspan>
      </text>
    </g>
  );
}

function TrendTooltip({ active, payload, label }: Record<string, unknown>) {
  if (!active) return null;
  const items = payload as Array<{ name: string; value: number; color: string; dataKey: string }> | undefined;
  if (!items?.length) return null;
  const ts = typeof label === 'number' ? new Date(label).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }) : String(label ?? '');
  return (
    <div className="rounded-lg border border-surface-700 bg-surface-900 px-3 py-2 text-xs shadow-lg">
      <div className="mb-1 text-gray-400">{ts}</div>
      {items.map((item, i) => (
        <div key={i} className="flex justify-between gap-4" style={{ color: item.color }}>
          <span>{item.name}:</span>
          <span className="font-semibold">
            {item.dataKey === 'price' ? `$${item.value.toFixed(2)}` : `${item.value}%`}
          </span>
        </div>
      ))}
    </div>
  );
}

function PositionCard({ positions, ticker }: { positions: import('../api/hooks').Position[]; ticker: string }) {
  const pos = positions.find((p) => p.ticker === ticker && p.quantity > 0);
  if (!pos) return null;

  const marketValue = pos.current_price ? pos.quantity * pos.current_price : null;
  const pnlColor = (pos.unrealized_pnl ?? 0) >= 0 ? 'text-green-400' : 'text-red-400';
  const pnlSign = (pos.unrealized_pnl ?? 0) >= 0 ? '+' : '';

  return (
    <Card>
      <div className="flex items-center justify-between">
        <h2 className="text-sm font-medium text-gray-400">Open Position</h2>
        <StatusBadge status="active" />
      </div>
      <dl className="mt-2 grid grid-cols-2 gap-x-8 gap-y-2 text-sm sm:grid-cols-5">
        <div>
          <dt className="text-gray-500">Shares</dt>
          <dd className="font-mono text-gray-200">{pos.quantity}</dd>
        </div>
        <div>
          <dt className="text-gray-500">Avg Entry</dt>
          <dd className="font-mono text-gray-200">${pos.avg_entry_price.toFixed(2)}</dd>
        </div>
        <div>
          <dt className="text-gray-500">Current Price</dt>
          <dd className="font-mono text-gray-200">{pos.current_price ? `$${pos.current_price.toFixed(2)}` : '—'}</dd>
        </div>
        <div>
          <dt className="text-gray-500">Market Value</dt>
          <dd className="font-mono text-gray-200">{marketValue ? `$${marketValue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` : '—'}</dd>
        </div>
        <div>
          <dt className="text-gray-500">Unrealized P&L</dt>
          <dd className={`font-mono font-semibold ${pnlColor}`}>
            {pos.unrealized_pnl != null ? `${pnlSign}$${Math.abs(pos.unrealized_pnl).toFixed(2)}` : '—'}
          </dd>
        </div>
      </dl>
    </Card>
  );
}

function TrendHistoryChart({ trends, latestTrends, ticker, marketPrices, range90d, selectedWindow, onWindowChange }: { trends: TrendSummary[]; latestTrends: TrendSummary[]; ticker: string; marketPrices: MarketPrice[]; range90d: { low: number | null; high: number | null }; selectedWindow: string; onWindowChange: (w: string) => void }) {

  // Determine the time range for the selected window to filter data
  const windowHours: Record<string, number> = {
    intraday: 24,
    '1d': 48,
    '7d': 7 * 24,
    '30d': 30 * 24,
    '90d': 90 * 24,
  };
  const hoursBack = windowHours[selectedWindow] ?? 7 * 24;
  const cutoffTs = Date.now() - hoursBack * 3600_000;

  // Use history data for charts — filter to selected window and time range
  const filtered = (trends ?? [])
    .filter((t) => t.entity_id === ticker && t.window === selectedWindow && new Date(t.generated_at).getTime() >= cutoffTs)
    .sort((a, b) => new Date(a.generated_at).getTime() - new Date(b.generated_at).getTime());

  // Build a price lookup — match by closest timestamp to each trend point
  const sortedPrices = [...(marketPrices ?? [])]
    .filter((p) => p.bar_timestamp != null && p.close != null)
    .sort((a, b) => a.bar_timestamp - b.bar_timestamp);

  // Filter prices to the selected window's time range (use all prices if sparse)
  const windowPrices = sortedPrices.length <= 20 ? sortedPrices : sortedPrices.filter((p) => p.bar_timestamp >= cutoffTs);

  function findClosestPrice(ts: number): number | undefined {
    if (windowPrices.length === 0) return undefined;
    let best = windowPrices[0];
    let bestDiff = Math.abs(ts - best.bar_timestamp);
    for (const p of windowPrices) {
      const diff = Math.abs(ts - p.bar_timestamp);
      if (diff < bestDiff) {
        best = p;
        bestDiff = diff;
      }
    }
    // Match if within reasonable gap for the window type
    // With sparse price data (~1 bar per 4-6 hours), use wider tolerances
    const maxGapHours: Record<string, number> = {
      intraday: 6,
      '1d': 12,
      '7d': 36,
      '30d': 72,
      '90d': 168,
    };
    const maxGap = (maxGapHours[selectedWindow] ?? 36) * 3600_000;
    return bestDiff <= maxGap ? best.close : undefined;
  }

  const chartData: ChartPoint[] = filtered.map((t) => {
    const trendTs = new Date(t.generated_at).getTime();
    const price = findClosestPrice(trendTs);
    return {
      time: String(trendTs),
      timestamp: trendTs,
      strength: +(t.trend_strength * 100).toFixed(1),
      confidence: +(t.confidence * 100).toFixed(1),
      contradiction: +(t.contradiction_score * 100).toFixed(1),
      direction: DIRECTION_VALUE[t.trend_direction] ?? 0,
      directionLabel: t.trend_direction,
      window: t.window,
      price,
    };
  });

  const hasPrice = chartData.some((pt) => pt.price != null);

  // Compute market open/close vertical markers for intraday and 1d windows
  const showMarketMarkers = selectedWindow === 'intraday' || selectedWindow === '1d';
  const marketMarkers: { ts: number; label: string }[] = [];
  if (showMarketMarkers && chartData.length > 0) {
    const minTs = chartData[0].timestamp;
    const maxTs = chartData[chartData.length - 1].timestamp;
    // Walk each day in the range and compute 9:30 AM ET (open) and 4:00 PM ET (close)
    const dayMs = 86400_000;
    const startDay = new Date(minTs);
    startDay.setUTCHours(0, 0, 0, 0);
    for (let d = startDay.getTime(); d <= maxTs + dayMs; d += dayMs) {
      const date = new Date(d);
      const dow = date.getUTCDay();
      if (dow === 0 || dow === 6) continue; // skip weekends
      // ET offset: EDT = UTC-4, EST = UTC-5. Approximate with -4 (summer).
      // 9:30 AM ET = 13:30 UTC (EDT)
      const openTs = d + 13 * 3600_000 + 30 * 60_000;
      // 4:00 PM ET = 20:00 UTC (EDT)
      const closeTs = d + 20 * 3600_000;
      if (openTs >= minTs && openTs <= maxTs) {
        marketMarkers.push({ ts: openTs, label: 'Open' });
      }
      if (closeTs >= minTs && closeTs <= maxTs) {
        marketMarkers.push({ ts: closeTs, label: 'Close' });
      }
    }
  }

  // Available windows from the data (check both history and latest)
  const allTrends = [...(trends ?? []), ...(latestTrends ?? [])];
  const availableWindows = [...new Set(allTrends.filter((t) => t.entity_id === ticker).map((t) => t.window))];
  availableWindows.sort((a, b) => WINDOW_ORDER.indexOf(a) - WINDOW_ORDER.indexOf(b));

  // Use latest trends for the summary card
  const latestForWindow = (latestTrends ?? [])
    .filter((t) => t.entity_id === ticker && t.window === selectedWindow)
    .sort((a, b) => new Date(b.generated_at).getTime() - new Date(a.generated_at).getTime());
  const latest = latestForWindow[0] ?? (filtered.length > 0 ? filtered[filtered.length - 1] : null);

  const [fullscreen, setFullscreen] = useState(false);

  // Close fullscreen on Escape key
  useEffect(() => {
    if (!fullscreen) return;
    const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') setFullscreen(false); };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [fullscreen]);

  // Shared chart content — rendered at different sizes
  const chartContent = (height: number) => (
    <ResponsiveContainer width="100%" height={height}>
      <LineChart data={chartData} margin={{ top: 5, right: 20, bottom: 70, left: 0 }}>
        <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
        {marketMarkers.map((m, i) => (
          <ReferenceLine
            key={`market-${i}`}
            yAxisId="left"
            x={m.ts}
            stroke={m.label === 'Open' ? '#22c55e' : '#ef4444'}
            strokeDasharray="4 4"
            strokeWidth={1}
            strokeOpacity={0.5}
            label={{ value: m.label, position: 'top', fill: m.label === 'Open' ? '#22c55e' : '#ef4444', fontSize: 9 }}
          />
        ))}
        <XAxis
          dataKey="timestamp"
          type="number"
          domain={['dataMin', 'dataMax']}
          scale="time"
          tick={<ChartXTick />}
          tickLine={{ stroke: '#475569' }}
          tickCount={8}
        />
        <YAxis
          yAxisId="left"
          domain={[0, 100]}
          tick={{ fill: '#94a3b8', fontSize: 11 }}
          tickLine={{ stroke: '#475569' }}
          tickFormatter={(v) => `${v}%`}
        />
        {hasPrice && (
          <YAxis
            yAxisId="right"
            orientation="right"
            tick={{ fill: '#e879f9', fontSize: 11 }}
            tickLine={{ stroke: '#475569' }}
            tickFormatter={(v) => `$${v}`}
            domain={[
              range90d.low != null ? Math.floor(range90d.low * 0.97) : 'dataMin - 2',
              range90d.high != null ? Math.ceil(range90d.high * 1.03) : 'dataMax + 2',
            ]}
          />
        )}
        <Tooltip content={TrendTooltip} />
        <Legend verticalAlign="bottom" wrapperStyle={{ color: '#94a3b8', fontSize: 12, paddingTop: 24 }} />
        {hasPrice && range90d.high != null && (
          <ReferenceLine
            yAxisId="right"
            y={range90d.high}
            stroke="#22c55e"
            strokeDasharray="6 3"
            strokeWidth={1.5}
            label={{ value: `90d High $${range90d.high.toFixed(2)}`, position: 'insideTopRight', fill: '#22c55e', fontSize: 10 }}
          />
        )}
        {hasPrice && range90d.low != null && (
          <ReferenceLine
            yAxisId="right"
            y={range90d.low}
            stroke="#ef4444"
            strokeDasharray="6 3"
            strokeWidth={1.5}
            label={{ value: `90d Low $${range90d.low.toFixed(2)}`, position: 'insideBottomRight', fill: '#ef4444', fontSize: 10 }}
          />
        )}
        <Line yAxisId="left" type="monotone" dataKey="strength" name="Trend Strength" stroke="#3b82f6" strokeWidth={2} dot={{ r: 3, fill: '#3b82f6' }} activeDot={{ r: 5 }} />
        <Line yAxisId="left" type="monotone" dataKey="confidence" name="Confidence" stroke="#10b981" strokeWidth={2} dot={{ r: 3, fill: '#10b981' }} activeDot={{ r: 5 }} />
        <Line yAxisId="left" type="monotone" dataKey="contradiction" name="Contradiction" stroke="#f59e0b" strokeWidth={1.5} strokeDasharray="5 5" dot={{ r: 2, fill: '#f59e0b' }} />
        {hasPrice && (
          <Line yAxisId="right" type="monotone" dataKey="price" name="Price" stroke="#e879f9" strokeWidth={2} dot={{ r: 3, fill: '#e879f9' }} activeDot={{ r: 5 }} connectNulls />
        )}
      </LineChart>
    </ResponsiveContainer>
  );

  return (
    <div className="space-y-4">
      {/* Window selector */}
      <div className="flex items-center gap-3">
        <span className="text-sm text-gray-400">Window:</span>
        {(availableWindows.length > 0 ? availableWindows : WINDOW_ORDER).map((w) => (
          <button
            key={w}
            onClick={() => onWindowChange(w)}
            className={`rounded-md px-3 py-1 text-xs font-medium transition-colors ${
              selectedWindow === w
                ? 'bg-brand-600 text-white'
                : 'border border-surface-700 bg-surface-900 text-gray-400 hover:bg-surface-800'
            }`}
          >
            {w}
          </button>
        ))}
      </div>

      {chartData.length === 0 ? (
        <Card>
          <p className="text-sm text-gray-500">No trend history for {ticker} / {selectedWindow}</p>
        </Card>
      ) : (
        <>
          {/* Trend Strength & Confidence Chart */}
          <Card>
            <div className="mb-3 flex items-center justify-between">
              <h2 className="text-sm font-medium text-gray-400">
                Trend Strength & Confidence — {ticker} / {selectedWindow}
              </h2>
              <button
                onClick={() => setFullscreen(true)}
                className="rounded-md border border-surface-700 px-2 py-1 text-xs text-gray-400 hover:bg-surface-800 hover:text-gray-200"
                title="Expand chart"
              >
                ⛶ Expand
              </button>
            </div>
            {chartContent(280)}
          </Card>

          {/* Fullscreen overlay */}
          {fullscreen && (
            <div
              className="fixed inset-0 z-50 flex flex-col bg-surface-950/95 p-6"
              onClick={(e) => { if (e.target === e.currentTarget) setFullscreen(false); }}
              role="dialog"
              aria-label="Expanded chart"
            >
              <div className="mb-4 flex items-center justify-between">
                <h2 className="text-lg font-medium text-gray-200">
                  Trend Strength & Confidence — {ticker} / {selectedWindow}
                </h2>
                <button
                  onClick={() => setFullscreen(false)}
                  className="rounded-md border border-surface-700 px-3 py-1.5 text-sm text-gray-400 hover:bg-surface-800 hover:text-gray-200"
                >
                  ✕ Close
                </button>
              </div>
              <div className="flex-1 min-h-0">
                {chartContent(Math.max(400, window.innerHeight - 160))}
              </div>
            </div>
          )}

          {/* Direction Timeline */}
          {/* Direction Timeline */}
          <Card>
            <h2 className="mb-3 text-sm font-medium text-gray-400">
              Direction Timeline — {ticker} / {selectedWindow}
            </h2>
            <div className="flex items-end gap-1 overflow-x-auto pb-2" style={{ minHeight: 60 }}>
              {chartData.map((pt, i) => {
                const color =
                  pt.directionLabel === 'bullish' ? 'bg-green-500' :
                  pt.directionLabel === 'bearish' ? 'bg-red-500' :
                  pt.directionLabel === 'mixed' ? 'bg-yellow-500' :
                  'bg-gray-600';
                const height = Math.max(8, pt.strength * 0.5);
                return (
                  <div key={i} className="flex flex-col items-center gap-1" title={`${new Date(pt.timestamp).toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })}: ${pt.directionLabel} (${pt.strength}%)`}>
                    <div
                      className={`w-3 rounded-sm ${color}`}
                      style={{ height: `${height}px` }}
                    />
                    {i % Math.max(1, Math.floor(chartData.length / 8)) === 0 && (
                      <span className="text-[9px] text-gray-500 -rotate-45 origin-top-left whitespace-nowrap">{new Date(pt.timestamp).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })}</span>
                    )}
                  </div>
                );
              })}
            </div>
            <div className="mt-2 flex gap-4 text-xs text-gray-500">
              <span className="flex items-center gap-1"><span className="inline-block w-2 h-2 rounded-sm bg-green-500" /> Bullish</span>
              <span className="flex items-center gap-1"><span className="inline-block w-2 h-2 rounded-sm bg-red-500" /> Bearish</span>
              <span className="flex items-center gap-1"><span className="inline-block w-2 h-2 rounded-sm bg-yellow-500" /> Mixed</span>
              <span className="flex items-center gap-1"><span className="inline-block w-2 h-2 rounded-sm bg-gray-600" /> Neutral</span>
            </div>
          </Card>

          {/* Latest trend summary */}
          <Card>
            <h2 className="mb-3 text-sm font-medium text-gray-400">Latest Trend</h2>
            {latest && (() => {
              return (
                <dl className="grid grid-cols-2 gap-x-8 gap-y-2 text-sm sm:grid-cols-4">
                  <div>
                    <dt className="text-gray-500">Direction</dt>
                    <dd><StatusBadge status={latest.trend_direction} /></dd>
                  </div>
                  <div>
                    <dt className="text-gray-500">Strength</dt>
                    <dd><ConfidenceBar value={latest.trend_strength} /></dd>
                  </div>
                  <div>
                    <dt className="text-gray-500">Confidence</dt>
                    <dd><ConfidenceBar value={latest.confidence} /></dd>
                  </div>
                  <div>
                    <dt className="text-gray-500">Contradiction</dt>
                    <dd className={`font-mono ${latest.contradiction_score > 0.5 ? 'text-yellow-400' : 'text-gray-300'}`}>
                      {(latest.contradiction_score * 100).toFixed(0)}%
                    </dd>
                  </div>
                  <div>
                    <dt className="text-gray-500">Catalysts</dt>
                    <dd className="flex flex-wrap gap-1">
                      {(latest.dominant_catalysts ?? []).map((c, i) => (
                        <span key={i} className="rounded bg-surface-800 px-1.5 py-0.5 text-[10px] text-gray-300">{c}</span>
                      ))}
                    </dd>
                  </div>
                  <div>
                    <dt className="text-gray-500">Generated</dt>
                    <dd className="text-gray-300">{new Date(latest.generated_at).toLocaleString()}</dd>
                  </div>
                </dl>
              );
            })()}
          </Card>
        </>
      )}
    </div>
  );
}
