/**
 * PageStateContext — preserves page-level session state across route changes.
 *
 * When React Router unmounts a page component, all its useState values are lost.
 * This context lives above the router and holds the state that must survive
 * navigation so users can switch modules and return without losing their work.
 *
 * Covered pages:
 *  - RagChat:    message history, citation rail, sessionId, input draft
 *  - Compliance: analysis result (sources, findings, conclusion, meta)
 *  - Perception: selected signal, filter state, AI analysis output
 */

import React, { createContext, useContext, useState, useCallback, useRef } from 'react';

// ── RagChat types ─────────────────────────────────────────────────────────────

export interface RagMessage {
  id: string;
  role: 'user' | 'assistant';
  text: string;
  citationRefs?: number[];
}

export interface RagCitation {
  index: number;
  score: number;
  name: string;
  clause: string;
  snippet: string;
  docId?: string;
}

export interface RagChatState {
  messages: RagMessage[];
  citations: RagCitation[];
  sessionId: string | null;
  inputDraft: string;
}

const RAG_INIT: RagChatState = {
  messages: [
    {
      id: 'init',
      role: 'assistant',
      text: 'Hello! I can answer questions about your indexed regulations and compliance documents. Try asking about EU AI Act requirements, MIIT rules, or ISO/SAE 21434 scope.',
    },
  ],
  citations: [],
  sessionId: null,
  inputDraft: '',
};

// ── Compliance types ──────────────────────────────────────────────────────────

export interface ComplianceSourceEvent {
  standard: string;
  clause: string;
  score: number;
  status: string;
  full_content: string;
  /** Index of the clause this source was retrieved for (for source↔finding linking) */
  clause_index?: number;
}

export interface ComplianceFindingEvent {
  title: string;
  desc: string;
  status: 'ok' | 'warn' | 'risk';
  clause_ref?: string;
  /** LLM confidence that retrieved context covers the clause topic (0–1) */
  confidence?: number;
  /** Top-3 regulation chunks that informed this finding */
  source_refs?: Array<{ standard: string; clause: string; score: number }>;
}

export interface ComplianceConflict {
  type: 'contradiction' | 'missing_ref' | 'cumulative_risk';
  finding_a: number;
  finding_b: number | null;
  desc: string;
}

export interface ComplianceActionItem {
  label: string;
  value: string;
  risk?: boolean;
}

export interface ComplianceDonePayload {
  conclusion: string;
  actions: ComplianceActionItem[];
  risk_score: number;
  highlight_terms: string[];
  para_text: string;
}

export interface ComplianceMeta {
  title: string;
  sourceType: 'text' | 'doc' | 'upload';
  startedAt: string;
}

export type ComplianceStatus = 'idle' | 'streaming' | 'done' | 'error';

export interface ComplianceState {
  status: ComplianceStatus;
  stageLabel: string;
  stageKey: string;
  meta: ComplianceMeta | null;
  sources: ComplianceSourceEvent[];
  findings: ComplianceFindingEvent[];
  done: ComplianceDonePayload | null;
  errorText: string;
  // Direction B additions:
  analysisId: string | null;
  isReadOnly: boolean;
  activeFindingId: string | null;
  /** Real-time per-clause progress {done, total} */
  progress: { done: number; total: number } | null;
  /** Cross-clause conflicts detected after all findings complete */
  conflicts: ComplianceConflict[];
}

const COMPLIANCE_INIT: ComplianceState = {
  status: 'idle',
  stageLabel: '',
  stageKey: '',
  meta: null,
  sources: [],
  findings: [],
  done: null,
  errorText: '',
  analysisId: null,
  isReadOnly: false,
  activeFindingId: null,
  progress: null,
  conflicts: [],
};

// ── Perception types ──────────────────────────────────────────────────────────

export interface PerceptionSignal {
  id: string;
  source: string;
  standard: string;
  status: 'ok' | 'warn' | 'risk' | 'info';
  title: string;
  summary: string;
  date: string;
  tags: string[];
  impact: 'High' | 'Medium' | 'Low';
}

export interface PerceptionPageState {
  signals: PerceptionSignal[];
  searchQuery: string;
  sourceFilter: string;
  impactFilter: string;
  selectedId: string | null;
  aiOutput: string;
  detailTab: 'overview' | 'obligations' | 'assessment' | 'diff';
  crawlStatus: string;
}

const PERCEPTION_INIT: PerceptionPageState = {
  signals: [],
  searchQuery: '',
  sourceFilter: 'All',
  impactFilter: 'All',
  selectedId: null,
  aiOutput: '',
  detailTab: 'overview',
  crawlStatus: '',
};

// ── Context value ─────────────────────────────────────────────────────────────

interface PageStateContextValue {
  // RagChat
  ragState: RagChatState;
  setRagState: React.Dispatch<React.SetStateAction<RagChatState>>;
  ragStreamingRef: React.MutableRefObject<boolean>;
  ragAbortRef: React.MutableRefObject<AbortController | null>;

  // Compliance
  complianceState: ComplianceState;
  setComplianceState: React.Dispatch<React.SetStateAction<ComplianceState>>;
  complianceAbortRef: React.MutableRefObject<AbortController | null>;
  resetCompliance: () => void;

  // Perception
  perceptionState: PerceptionPageState;
  setPerceptionState: React.Dispatch<React.SetStateAction<PerceptionPageState>>;
  perceptionAbortRef: React.MutableRefObject<AbortController | null>;
  perceptionCrawlAbortRef: React.MutableRefObject<AbortController | null>;
}

const PageStateContext = createContext<PageStateContextValue | null>(null);

// ── Provider ──────────────────────────────────────────────────────────────────

export function PageStateProvider({ children }: { children: React.ReactNode }) {
  const [ragState, setRagState] = useState<RagChatState>(RAG_INIT);
  const ragStreamingRef = useRef(false);
  const ragAbortRef = useRef<AbortController | null>(null);

  const [complianceState, setComplianceState] = useState<ComplianceState>(COMPLIANCE_INIT);
  const complianceAbortRef = useRef<AbortController | null>(null);

  const resetCompliance = useCallback(() => {
    complianceAbortRef.current?.abort();
    setComplianceState(COMPLIANCE_INIT);
  }, []);

  const [perceptionState, setPerceptionState] = useState<PerceptionPageState>(PERCEPTION_INIT);
  const perceptionAbortRef = useRef<AbortController | null>(null);
  const perceptionCrawlAbortRef = useRef<AbortController | null>(null);

  return (
    <PageStateContext.Provider value={{
      ragState, setRagState, ragStreamingRef, ragAbortRef,
      complianceState, setComplianceState, complianceAbortRef, resetCompliance,
      perceptionState, setPerceptionState, perceptionAbortRef, perceptionCrawlAbortRef,
    }}>
      {children}
    </PageStateContext.Provider>
  );
}

// ── Hook ──────────────────────────────────────────────────────────────────────

export function usePageState() {
  const ctx = useContext(PageStateContext);
  if (!ctx) throw new Error('usePageState must be used inside PageStateProvider');
  return ctx;
}
