import { Fragment, useState } from 'react';
import type { ExpandedQuery, ScoredChunk, RRFResult, RerankedResult, FinalResult } from '../types';
import ExpansionColumn from './ExpansionColumn';
import SearchColumn from './SearchColumn';
import FusionColumn from './FusionColumn';
import ResultCard from './ResultCard';

export interface PipelineState {
  expansion: { status: 'idle' | 'running' | 'done' | 'error'; data?: ExpandedQuery; error?: string };
  search: { status: 'idle' | 'running' | 'done'; data?: { bm25Hits: ScoredChunk[]; vectorHits: ScoredChunk[] } };
  rrf: { status: 'idle' | 'done'; data?: { merged: RRFResult[] } };
  rerank: { status: 'idle' | 'running' | 'done'; data?: { before: RRFResult[]; after: RerankedResult[] } };
  blend: { status: 'idle' | 'done'; data?: { finalResults: FinalResult[] } };
}

interface PipelineViewProps {
  state: PipelineState;
  query?: string;
  intent?: string;
}

const STAGES = [
  {
    label: 'User Query',
    accent: '#5c6bc0',
    info: 'The original search query you typed. This is the starting point for the entire pipeline.',
  },
  {
    label: 'Query Expansion',
    accent: '#f57f17',
    info: 'A compact 1.7B LLM (cached locally) generates lexical keywords (lex), semantic sentences (vec), and a hypothetical document (HyDE). When BM25 already has a strong exact match, expansion is skipped.',
  },
  {
    label: 'Parallel Search',
    accent: '#00897b',
    info: 'The original query always runs through BM25 and vector search. Lex variants route only to BM25, while vec and HyDE variants route to vector search, mirroring qmd\'s typed retrieval flow.',
  },
  {
    label: 'Fusion & Reranking',
    accent: '#388e3c',
    info: 'Results are merged via Reciprocal Rank Fusion (RRF), then a cross-encoder reranker (Qwen3-Reranker-0.6B) re-scores the top candidates. Final ranking blends reranker confidence with RRF position.',
  },
];

function InfoTooltip({ text }: { text: string }) {
  const [open, setOpen] = useState(false);

  return (
    <span
      style={{ position: 'relative', display: 'inline-flex', alignItems: 'center' }}
      onMouseEnter={() => setOpen(true)}
      onMouseLeave={() => setOpen(false)}
      onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }}
    >
      <span style={{
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        width: '16px',
        height: '16px',
        borderRadius: '50%',
        border: '1px solid var(--border)',
        background: 'var(--bg-card)',
        color: 'var(--text-muted)',
        fontSize: '0.62rem',
        fontWeight: 700,
        cursor: 'help',
        flexShrink: 0,
        lineHeight: 1,
      }}>
        ?
      </span>
      {open && (
        <div style={{
          position: 'absolute',
          top: '100%',
          left: '50%',
          transform: 'translateX(-50%)',
          marginTop: '6px',
          padding: '0.6rem 0.75rem',
          background: 'var(--bg-card)',
          border: '1px solid var(--border)',
          borderRadius: '6px',
          boxShadow: '0 4px 16px var(--shadow)',
          fontSize: '0.72rem',
          fontFamily: 'system-ui, -apple-system, sans-serif',
          fontWeight: 400,
          color: 'var(--text)',
          lineHeight: 1.55,
          width: '220px',
          zIndex: 100,
          textTransform: 'none',
          letterSpacing: 'normal',
        }}>
          {text}
        </div>
      )}
    </span>
  );
}

function StageHeader({ label, accent, info }: { label: string; accent: string; info: string }) {
  return (
    <div style={{
      display: 'flex',
      alignItems: 'center',
      gap: '0.4rem',
      marginBottom: '0.75rem',
      paddingBottom: '0.5rem',
      borderBottom: '1px solid var(--stage-divider)',
    }}>
      <span style={{
        width: '3px',
        height: '14px',
        borderRadius: '2px',
        background: accent,
        flexShrink: 0,
      }} />
      <h3 style={{
        margin: 0,
        fontSize: '0.78rem',
        fontFamily: 'system-ui, -apple-system, sans-serif',
        fontWeight: 700,
        color: accent,
        textTransform: 'uppercase',
        letterSpacing: '0.05em',
      }}>
        {label}
      </h3>
      <InfoTooltip text={info} />
    </div>
  );
}

// Horizontal header band showing stage flow: Stage 1 › Stage 2 › Stage 3 › Stage 4
function StageFlowHeader() {
  return (
    <div style={{
      display: 'flex',
      alignItems: 'center',
      gap: '0.3rem',
      padding: '0.55rem 0.85rem',
      borderBottom: '1px solid var(--pipeline-border)',
      flexWrap: 'wrap',
    }}>
      {STAGES.map((stage, i) => (
        <Fragment key={stage.label}>
          {i > 0 && (
            <span style={{
              color: 'var(--text-muted)',
              fontSize: '0.7rem',
              opacity: 0.5,
              margin: '0 0.15rem',
            }}>
              {'\u203A'}
            </span>
          )}
          <span style={{
            fontSize: '0.68rem',
            fontWeight: 700,
            fontFamily: 'system-ui, -apple-system, sans-serif',
            color: stage.accent,
            textTransform: 'uppercase',
            letterSpacing: '0.04em',
          }}>
            {stage.label}
          </span>
        </Fragment>
      ))}
    </div>
  );
}

function QueryColumn({ query, intent, accent, info }: { query?: string; intent?: string; accent: string; info: string }) {
  return (
    <div>
      <StageHeader label="User Query" accent={accent} info={info} />
      {query ? (
        <>
          <div style={{
            padding: '0.55rem 0.75rem',
            background: 'var(--bg-card)',
            border: '1px solid var(--border)',
            borderRadius: '6px',
            fontFamily: "'SF Mono', 'Fira Code', 'Cascadia Code', monospace",
            fontSize: '0.82rem',
            color: 'var(--text)',
            wordBreak: 'break-word',
            lineHeight: 1.5,
          }}>
            {query}
          </div>
          {intent && (
            <div style={{
              marginTop: '0.35rem',
              padding: '0.4rem 0.65rem',
              background: 'var(--bg-card)',
              border: '1px solid #f57f1730',
              borderRadius: '6px',
              fontSize: '0.72rem',
              lineHeight: 1.4,
            }}>
              <span style={{
                fontFamily: 'system-ui, -apple-system, sans-serif',
                fontWeight: 700,
                color: '#f57f17',
                textTransform: 'uppercase',
                fontSize: '0.62rem',
                letterSpacing: '0.04em',
              }}>
                Intent
              </span>
              <div style={{
                fontFamily: "'SF Mono', 'Fira Code', 'Cascadia Code', monospace",
                color: 'var(--text-secondary)',
                marginTop: '0.15rem',
              }}>
                {intent}
              </div>
            </div>
          )}
        </>
      ) : (
        <p style={{
          fontFamily: 'system-ui, -apple-system, sans-serif',
          fontSize: '0.8rem',
          color: 'var(--text-muted)',
          margin: 0,
        }}>
          No query yet.
        </p>
      )}
    </div>
  );
}

function FinalResultsPanel({ results }: { results: FinalResult[] }) {
  return (
    <div style={{
      padding: '0.85rem',
      borderTop: '1px solid var(--pipeline-border)',
    }}>
      <div style={{
        display: 'flex',
        alignItems: 'center',
        gap: '0.4rem',
        marginBottom: '0.6rem',
      }}>
        <span style={{
          width: '3px',
          height: '14px',
          borderRadius: '2px',
          background: '#1b5e20',
          flexShrink: 0,
        }} />
        <h3 style={{
          margin: 0,
          fontSize: '0.82rem',
          fontFamily: 'system-ui, -apple-system, sans-serif',
          fontWeight: 700,
          color: '#1b5e20',
          textTransform: 'uppercase',
          letterSpacing: '0.05em',
        }}>
          Final Results
        </h3>
        <span style={{
          fontSize: '0.68rem',
          fontFamily: 'system-ui, -apple-system, sans-serif',
          color: 'var(--text-muted)',
        }}>
          ({results.length} docs)
        </span>
      </div>
      <div style={{
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
        gap: '0.4rem',
      }}>
        {results.slice(0, 5).map(r => (
          <ResultCard
            key={r.docId}
            title={r.title}
            score={r.score}
            snippet={r.bestChunk}
          />
        ))}
      </div>
    </div>
  );
}

export default function PipelineView({ state, query, intent }: PipelineViewProps) {
  const blendDone = state.blend.status === 'done';
  const finalResults = state.blend.data?.finalResults;

  return (
    <>
      <style>{`
        @keyframes spin {
          to { transform: rotate(360deg); }
        }
      `}</style>

      <div style={{
        borderRadius: '10px',
        overflow: 'hidden',
        border: '1px solid var(--pipeline-border)',
        background: 'var(--pipeline-bg)',
        boxShadow: '0 2px 12px var(--shadow)',
        marginBottom: '1.5rem',
      }}>
        {/* Flow header band */}
        <StageFlowHeader />

        {/* Process row: 4 stages, align-items: start so columns shrink to content */}
        <div
          className="pipeline-grid"
          style={{
            display: 'grid',
            gridTemplateColumns: 'minmax(100px, 0.6fr) minmax(110px, 0.7fr) minmax(200px, 1.5fr) minmax(200px, 1.5fr)',
            gap: '0',
            alignItems: 'start',
          }}
        >
          {STAGES.map((col, i) => (
            <div
              key={col.label}
              className="pipeline-cell"
              style={{
                padding: '0.85rem',
                borderTop: `3px solid ${col.accent}`,
                borderRight: i < STAGES.length - 1 ? '1px solid var(--pipeline-border)' : 'none',
              }}
            >
              {i === 0 && <QueryColumn query={query} intent={intent} accent={col.accent} info={col.info} />}
              {i === 1 && <ExpansionColumn state={state.expansion} accent={col.accent} info={col.info} />}
              {i === 2 && <SearchColumn state={state.search} accent={col.accent} info={col.info} />}
              {i === 3 && (
                <FusionColumn state={{
                  rrf: state.rrf,
                  rerank: state.rerank,
                  finalResults: finalResults,
                }} accent={col.accent} info={col.info} />
              )}
            </div>
          ))}
        </div>

        {/* Results row: full-width below the process stages */}
        {blendDone && finalResults && finalResults.length > 0 && (
          <FinalResultsPanel results={finalResults} />
        )}
      </div>

      <style>{`
        @media (max-width: 768px) {
          .pipeline-grid {
            grid-template-columns: 1fr !important;
          }

          .pipeline-cell {
            border-right: none !important;
            border-bottom: 1px solid var(--pipeline-border);
          }

          .pipeline-cell:last-child {
            border-bottom: none;
          }
        }
      `}</style>
    </>
  );
}

export { InfoTooltip, StageHeader };
