'use client';

import { Fragment } from 'react';
import { ChevronDown, ChevronRight } from 'lucide-react';
import type { FinancialStatementPeriod, SurfaceFinancialRow, DetailFinancialRow } from '@/lib/types';
import { cn } from '@/lib/utils';
import type {
  StatementInspectorSelection,
  StatementTreeNode,
  StatementTreeSection
} from '@/lib/financials/statement-view-model';

type MatrixRow = SurfaceFinancialRow | DetailFinancialRow;

type StatementMatrixProps = {
  periods: FinancialStatementPeriod[];
  sections: StatementTreeSection[];
  selectedRowRef: StatementInspectorSelection | null;
  onToggleRow: (key: string) => void;
  onSelectRow: (selection: StatementInspectorSelection) => void;
  renderCellValue: (row: MatrixRow, periodId: string, previousPeriodId: string | null) => string;
  periodLabelFormatter: (value: string) => string;
};

function isSurfaceNode(node: StatementTreeNode): node is Extract<StatementTreeNode, { kind: 'surface' }> {
  return node.kind === 'surface';
}

function rowSelected(
  node: StatementTreeNode,
  selectedRowRef: StatementInspectorSelection | null
) {
  if (!selectedRowRef) {
    return false;
  }

  if (node.kind === 'surface') {
    return selectedRowRef.kind === 'surface' && selectedRowRef.key === node.row.key;
  }

  return selectedRowRef.kind === 'detail'
    && selectedRowRef.key === node.row.key
    && selectedRowRef.parentKey === node.parentSurfaceKey;
}

function surfaceBadges(node: Extract<StatementTreeNode, { kind: 'surface' }>) {
  const badges: Array<{ label: string; tone: 'default' | 'warning' | 'muted' }> = [];

  if (node.row.resolutionMethod === 'formula_derived') {
    badges.push({ label: 'Formula', tone: node.row.confidence === 'low' ? 'warning' : 'default' });
  }

  if (node.row.resolutionMethod === 'not_meaningful') {
    badges.push({ label: 'N/M', tone: 'muted' });
  }

  if (node.row.confidence === 'low') {
    badges.push({ label: 'Low confidence', tone: 'warning' });
  }

  const detailCount = node.row.detailCount ?? node.directDetailCount;
  if (detailCount > 0) {
    badges.push({ label: `${detailCount} details`, tone: 'default' });
  }

  return badges;
}

function badgeClass(tone: 'default' | 'warning' | 'muted') {
  if (tone === 'warning') {
    return 'border-[#84614f] bg-[rgba(112,76,54,0.22)] text-[#ffd7bf]';
  }

  if (tone === 'muted') {
    return 'border-[color:var(--line-weak)] bg-[rgba(80,85,92,0.16)] text-[color:var(--terminal-muted)]';
  }

  return 'border-[color:var(--line-weak)] bg-[rgba(88,102,122,0.16)] text-[color:var(--terminal-bright)]';
}

function renderNodes(props: StatementMatrixProps & { nodes: StatementTreeNode[] }) {
  return props.nodes.map((node) => {
    const isSelected = rowSelected(node, props.selectedRowRef);
    const labelIndent = node.kind === 'detail' ? node.level * 18 + 18 : node.level * 18;
    const canToggle = isSurfaceNode(node) && node.expandable;
    const nextSelection: StatementInspectorSelection = node.kind === 'surface'
      ? { kind: 'surface', key: node.row.key }
      : { kind: 'detail', key: node.row.key, parentKey: node.parentSurfaceKey };

    return (
      <Fragment key={node.id}>
        <tr className={cn(isSelected && 'bg-[color:rgba(70,77,87,0.48)]')}>
          <td className="sticky left-0 z-10 bg-[color:var(--panel)]">
            <div className="flex min-w-[260px] items-start gap-2" style={{ paddingLeft: `${labelIndent}px` }}>
              {canToggle ? (
                <button
                  type="button"
                  aria-label={`${node.expanded ? 'Collapse' : 'Expand'} ${node.row.label} details`}
                  aria-expanded={node.expanded}
                  aria-controls={`statement-children-${node.id}`}
                  className="mt-0.5 inline-flex size-11 shrink-0 items-center justify-center rounded-lg border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] text-[color:var(--terminal-bright)] transition hover:border-[color:var(--line-strong)]"
                  onClick={(event) => {
                    event.stopPropagation();
                    props.onToggleRow(node.row.key);
                  }}
                >
                  {node.expanded ? <ChevronDown className="size-4" /> : <ChevronRight className="size-4" />}
                </button>
              ) : (
                <span className="inline-flex size-11 shrink-0 items-center justify-center text-[color:var(--terminal-muted)]" aria-hidden="true">
                  {node.kind === 'detail' ? '·' : ''}
                </span>
              )}
              <button
                type="button"
                className="flex min-w-0 flex-1 flex-col items-start gap-1 py-2 text-left"
                onClick={() => props.onSelectRow(nextSelection)}
              >
                <span className={cn(
                  'text-sm text-[color:var(--terminal-bright)]',
                  node.kind === 'detail' && 'text-[13px] text-[color:var(--terminal-soft)]',
                  node.kind === 'surface' && node.level > 0 && 'text-[color:var(--terminal-soft)]'
                )}>
                  {node.row.label}
                </span>
                {node.kind === 'detail' ? (
                  <span className="text-xs text-[color:var(--terminal-muted)]">
                    {node.row.localName}
                    {node.row.residualFlag ? ' · residual' : ''}
                  </span>
                ) : (
                  <div className="flex flex-wrap gap-1">
                    {surfaceBadges(node).map((badge) => (
                      <span
                        key={`${node.row.key}-${badge.label}`}
                        className={cn(
                          'rounded-full border px-2 py-0.5 text-[10px] uppercase tracking-[0.14em]',
                          badgeClass(badge.tone)
                        )}
                      >
                        {badge.label}
                      </span>
                    ))}
                  </div>
                )}
              </button>
            </div>
          </td>
          {props.periods.map((period, index) => (
            <td key={`${node.id}-${period.id}`}>
              {props.renderCellValue(node.row, period.id, index > 0 ? props.periods[index - 1]?.id ?? null : null)}
            </td>
          ))}
        </tr>
        {isSurfaceNode(node) && node.expanded ? (
          <>
            <tr id={`statement-children-${node.id}`} className="sr-only">
              <td colSpan={props.periods.length + 1}>Expanded children for {node.row.label}</td>
            </tr>
            {renderNodes({
              ...props,
              nodes: node.children
            })}
          </>
        ) : null}
      </Fragment>
    );
  });
}

export function StatementMatrix(props: StatementMatrixProps) {
  return (
    <div className="data-table-wrap">
      <table className="data-table min-w-[1040px]">
        <thead>
          <tr>
            <th className="sticky left-0 z-10 bg-[color:var(--panel)]">Metric</th>
            {props.periods.map((period) => (
              <th key={period.id}>
                <div className="flex flex-col gap-1">
                  <span>{props.periodLabelFormatter(period.periodEnd ?? period.filingDate)}</span>
                  <span className="text-[11px] normal-case tracking-normal text-[color:var(--terminal-muted)]">{period.filingType} · {period.periodLabel}</span>
                </div>
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {props.sections.map((section) => (
            <Fragment key={section.key}>
              {section.label ? (
                <tr className="bg-[color:var(--panel-soft)]">
                  <td colSpan={props.periods.length + 1} className="font-semibold text-[color:var(--terminal-bright)]">
                    {section.label}
                  </td>
                </tr>
              ) : null}
              {renderNodes({
                ...props,
                nodes: section.nodes
              })}
            </Fragment>
          ))}
        </tbody>
      </table>
    </div>
  );
}
