import type {
  BalanceSheetPanelData,
  CashFlowPanelData,
  Company,
  DividendsPanelData,
  EarningsPanelData,
  FilingsPanelData,
  FinancialsPanelData,
  StockAnalysis,
} from '../types/financial';
import type { NewsArticle } from '../types/news';
import type { PanelPayload, TerminalEntry } from '../types/terminal';

export interface TerminalResearchNoteSeed {
  ticker?: string;
  contextLabel: string;
  rawText: string;
}

const findLatestPanel = (
  history: TerminalEntry[],
): { panel: PanelPayload; sourceCommand?: string } | null => {
  for (let index = history.length - 1; index >= 0; index -= 1) {
    const entry = history[index];
    if (entry.type !== 'panel' || typeof entry.content === 'string') {
      continue;
    }

    let sourceCommand: string | undefined;
    for (let commandIndex = index - 1; commandIndex >= 0; commandIndex -= 1) {
      const candidate = history[commandIndex];
      if (
        candidate.type === 'command' &&
        typeof candidate.content === 'string' &&
        candidate.content.startsWith('/')
      ) {
        sourceCommand = candidate.content;
        break;
      }
    }

    return {
      panel: entry.content,
      sourceCommand,
    };
  }

  return null;
};

const summarizeCompany = (company: Company, sourceCommand?: string) => [
  `Current terminal context: company snapshot for ${company.symbol} (${company.name}).`,
  sourceCommand ? `Source command: ${sourceCommand}` : null,
  `Price: $${company.price.toFixed(2)} (${company.change >= 0 ? '+' : ''}${company.change.toFixed(2)}, ${company.changePercent.toFixed(2)}%).`,
  company.profile?.sector ? `Sector: ${company.profile.sector}.` : null,
  company.profile?.description ? `Description: ${company.profile.description}` : null,
  '',
  'Analyst note:',
].filter(Boolean).join('\n');

const summarizeAnalysis = (analysis: StockAnalysis, sourceCommand?: string) => [
  `Current terminal context: analysis panel for ${analysis.symbol}.`,
  sourceCommand ? `Source command: ${sourceCommand}` : null,
  `Summary: ${analysis.summary}`,
  analysis.keyPoints.length > 0
    ? `Key points:\n${analysis.keyPoints.slice(0, 3).map((point) => `- ${point}`).join('\n')}`
    : null,
  analysis.risks.length > 0
    ? `Risks:\n${analysis.risks.slice(0, 2).map((risk) => `- ${risk}`).join('\n')}`
    : null,
  analysis.opportunities.length > 0
    ? `Opportunities:\n${analysis.opportunities.slice(0, 2).map((opportunity) => `- ${opportunity}`).join('\n')}`
    : null,
  '',
  'Analyst note:',
].filter(Boolean).join('\n');

const summarizeNews = (articles: NewsArticle[], ticker?: string, sourceCommand?: string) => [
  `Current terminal context: news${ticker ? ` for ${ticker}` : ''}.`,
  sourceCommand ? `Source command: ${sourceCommand}` : null,
  articles.length > 0
    ? `Top headlines:\n${articles.slice(0, 3).map((article) => `- ${article.headline}`).join('\n')}`
    : 'No recent headlines in the current panel.',
  '',
  'Analyst note:',
].filter(Boolean).join('\n');

const summarizeStatementPanel = (
  label: string,
  symbol: string,
  latestFiling: { form: string; filingDate: string } | undefined,
  rows: string[],
  sourceCommand?: string,
) => [
  `Current terminal context: ${label} for ${symbol}.`,
  sourceCommand ? `Source command: ${sourceCommand}` : null,
  latestFiling ? `Latest filing: ${latestFiling.form} filed ${latestFiling.filingDate}.` : null,
  rows.join('\n'),
  '',
  'Analyst note:',
].filter(Boolean).join('\n');

const summarizeFinancials = (
  panel: FinancialsPanelData,
  sourceCommand?: string,
) => {
  const latest = panel.periods[0];
  const rows = latest
    ? [
        `Latest period: ${latest.label}.`,
        latest.revenue != null ? `Revenue: ${latest.revenue.toLocaleString()}.` : null,
        latest.netIncome != null ? `Net income: ${latest.netIncome.toLocaleString()}.` : null,
      ].filter(Boolean) as string[]
    : ['No statement rows loaded.'];
  return summarizeStatementPanel('financial statements', panel.symbol, panel.latestFiling, rows, sourceCommand);
};

const summarizeCashFlow = (panel: CashFlowPanelData, sourceCommand?: string) => {
  const latest = panel.periods[0];
  const rows = latest
    ? [
        `Latest period: ${latest.label}.`,
        latest.netIncome != null ? `Net income: ${latest.netIncome.toLocaleString()}.` : null,
        latest.depreciationAndAmortization != null
          ? `Depreciation & amortization: ${latest.depreciationAndAmortization.toLocaleString()}.`
          : null,
        latest.operatingCashFlow != null
          ? `Operating cash flow: ${latest.operatingCashFlow.toLocaleString()}.`
          : null,
        latest.capex != null ? `Capital expenditures: ${latest.capex.toLocaleString()}.` : null,
        latest.freeCashFlow != null
          ? `Free cash flow: ${latest.freeCashFlow.toLocaleString()}.`
          : null,
        latest.investingCashFlow != null
          ? `Investing cash flow: ${latest.investingCashFlow.toLocaleString()}.`
          : null,
        latest.financingCashFlow != null
          ? `Financing cash flow: ${latest.financingCashFlow.toLocaleString()}.`
          : null,
        latest.dividendsPaid != null
          ? `Dividends paid: ${latest.dividendsPaid.toLocaleString()}.`
          : null,
        latest.stockRepurchases != null
          ? `Stock repurchases: ${latest.stockRepurchases.toLocaleString()}.`
          : null,
        latest.endingCash != null
          ? `Ending cash: ${latest.endingCash.toLocaleString()}.`
          : null,
      ].filter(Boolean) as string[]
    : ['No cash flow rows loaded.'];
  return summarizeStatementPanel('cash flow statement', panel.symbol, panel.latestFiling, rows, sourceCommand);
};

const summarizeBalanceSheet = (
  panel: BalanceSheetPanelData,
  sourceCommand?: string,
) => {
  const latest = panel.periods[0];
  const rows = latest
    ? [
        `Latest period: ${latest.label}.`,
        panel.selectedCurrency ? `Selected currency: ${panel.selectedCurrency}.` : null,
        latest.cashAndEquivalents != null
          ? `Cash: ${latest.cashAndEquivalents.toLocaleString()}.`
          : null,
        latest.totalAssets != null
          ? `Total assets: ${latest.totalAssets.toLocaleString()}.`
          : null,
        latest.totalLiabilities != null
          ? `Total liabilities: ${latest.totalLiabilities.toLocaleString()}.`
          : null,
        latest.totalEquity != null
          ? `Total equity: ${latest.totalEquity.toLocaleString()}.`
          : null,
      ].filter(Boolean) as string[]
    : ['No balance sheet rows loaded.'];
  return summarizeStatementPanel('balance sheet', panel.symbol, panel.latestFiling, rows, sourceCommand);
};

const summarizeDividends = (panel: DividendsPanelData, sourceCommand?: string) =>
  summarizeStatementPanel(
    'dividend history',
    panel.symbol,
    panel.latestFiling,
    [
      panel.latestEvent
        ? `Latest event: ${panel.latestEvent.endDate} (${panel.latestEvent.frequencyGuess}).`
        : 'No dividend event loaded.',
      panel.ttmDividendsPerShare != null
        ? `TTM dividends/share: ${panel.ttmDividendsPerShare.toFixed(2)}.`
        : null,
    ].filter(Boolean) as string[],
    sourceCommand,
  );

const summarizeEarnings = (panel: EarningsPanelData, sourceCommand?: string) => {
  const latest = panel.periods[0];
  const rows = latest
    ? [
        `Latest period: ${latest.label}.`,
        panel.selectedCurrency ? `Selected currency: ${panel.selectedCurrency}.` : null,
        latest.totalRevenues != null ? `Revenue: ${latest.totalRevenues.toLocaleString()}.` : null,
        latest.operatingProfit != null
          ? `Operating profit: ${latest.operatingProfit.toLocaleString()}.`
          : null,
        latest.consolidatedNetIncome != null
          ? `Net income: ${latest.consolidatedNetIncome.toLocaleString()}.`
          : null,
        latest.dilutedEps != null ? `Diluted EPS: ${latest.dilutedEps.toFixed(2)}.` : null,
        latest.effectiveTaxRate != null
          ? `Effective tax rate: ${latest.effectiveTaxRate.toFixed(1)}%.`
          : null,
      ].filter(Boolean) as string[]
    : ['No earnings rows loaded.'];
  return summarizeStatementPanel('earnings history', panel.symbol, panel.latestFiling, rows, sourceCommand);
};

const summarizeFilings = (panel: FilingsPanelData, sourceCommand?: string) =>
  summarizeStatementPanel(
    'filing history',
    panel.symbol,
    panel.latestFiling,
    [
      `Results: ${panel.totalResults}.`,
      `Page: ${panel.page} of ${panel.totalPages}.`,
      panel.query ? `Filter: ${panel.query}.` : null,
      panel.items[0]
        ? `Top result: ${panel.items[0].form} filed ${panel.items[0].filingDate}.`
        : 'No filing rows loaded.',
    ].filter(Boolean) as string[],
    sourceCommand,
  );

export const buildTerminalResearchNoteSeed = (
  history: TerminalEntry[],
): TerminalResearchNoteSeed | null => {
  const latestPanel = findLatestPanel(history);
  if (!latestPanel) {
    return null;
  }

  switch (latestPanel.panel.type) {
    case 'company':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} company context`,
        rawText: summarizeCompany(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'analysis':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} analysis context`,
        rawText: summarizeAnalysis(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'news':
      return {
        ticker: latestPanel.panel.ticker ?? latestPanel.panel.data[0]?.tickers[0],
        contextLabel: `${latestPanel.panel.ticker ?? 'Market'} news context`,
        rawText: summarizeNews(
          latestPanel.panel.data,
          latestPanel.panel.ticker,
          latestPanel.sourceCommand,
        ),
      };
    case 'financials':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} financial context`,
        rawText: summarizeFinancials(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'balanceSheet':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} balance sheet context`,
        rawText: summarizeBalanceSheet(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'cashFlow':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} cash flow context`,
        rawText: summarizeCashFlow(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'dividends':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} dividend context`,
        rawText: summarizeDividends(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'earnings':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} earnings context`,
        rawText: summarizeEarnings(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    case 'filings':
      return {
        ticker: latestPanel.panel.data.symbol,
        contextLabel: `${latestPanel.panel.data.symbol} filings context`,
        rawText: summarizeFilings(latestPanel.panel.data, latestPanel.sourceCommand),
      };
    default:
      return null;
  }
};
