'use client';

import React from 'react';
import { ExecutiveSummary } from '@/components/chat/ExecutiveSummary';
import { SourcesFootnotes } from '@/components/chat/SourcesFootnotes';
import { KeyDriversAccordion } from '@/components/chat/KeyDriversAccordion';
import { SourceVisualEvidenceAccordion } from '@/components/chat/SourceVisualEvidenceAccordion';
import { QuestionInput } from '@/components/chat/QuestionInput';
import { UnsupportedRequest, InsufficientEvidence } from '@/components/chat/StateCards';
import {
  submitQuestion,
  checkBackendHealth,
  type ChatResponse,
  normalizePageImageUrl,
} from '@/lib/api';

// Client-side domain guard (mirrors backend guardrail for instant UX feedback)
const OUT_OF_SCOPE_PATTERNS = [
  /\bweather\b/i, /\bsport(s)?\b/i, /\bfootball\b/i, /\bcricket\b/i,
  /\btemperature\b/i, /\bforecast\b/i, /\bclimate outside\b/i,
  /\btravel\b/i, /\bhotel\b/i, /\bflight\b/i, /\bmovie\b/i, /\bmusic\b/i,
  /\bpython\b/i, /\bjavascript\b/i, /\bcode\b/i, /\bprogram\b/i,
  /\bmedical\b/i, /\bdoctor\b/i, /\bhealth\b/i,
  /\blegal\b/i, /\blawyer\b/i,
  /\bpoliti/i, /\belection\b/i,
  /\bstock tip\b/i, /\bbuy.*shares?\b/i, /\binvest.*advice\b/i,
  /\bsalary\b/i, /\bhr\b/i,
  /system prompt/i, /prompt injection/i, /ignore.*instruct/i,
  /reveal.*prompt/i, /bypass/i, /api.?key/i,
  /vector.*database/i, /embedding.*model/i, /\brag\b/i,
];

type MessageType = 'question' | 'ir-response' | 'unsupported' | 'insufficient' | 'thinking';

interface Message {
  id: string;
  type: MessageType;
  content: string;
  response?: ChatResponse;
}

interface ResponseWorkspaceProps {
  onOpenPage: (docName: string, page: number) => void;
  onQuestionAsked?: (question: string) => void;
  triggeredQuestion?: string;
  onClearTriggeredQuestion?: () => void;
  selectedDocIds: string[];
}

/* ── Thinking Indicator ── */
function ThinkingIndicator() {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: '0.875rem',
      padding: '1rem 1.25rem',
      background: 'var(--bg-card)',
      border: '1px solid var(--border-subtle)',
      borderRadius: 'var(--radius-lg)',
      animation: 'fadeInUp 0.25s ease both',
    }}>
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src="/Emirates NBD Bank Logo.png"
        alt="Emirates NBD Logo"
        style={{
          height: '24px',
          width: 'auto',
          objectFit: 'contain',
          flexShrink: 0,
        }}
      />
      <div>
        <div style={{ fontSize: '0.72rem', color: 'var(--text-muted)', marginBottom: '0.3rem' }}>
          Retrieving and analysing Investor Relations evidence…
        </div>
        <div className="thinking-dots"><span /><span /><span /></div>
      </div>
    </div>
  );
}

/* ── Welcome Screen ── */
function WelcomeScreen({ backendLive }: { backendLive: boolean }) {
  return (
    <div className="welcome-screen">
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src="/Emirates NBD Bank Logo.png"
        alt="Emirates NBD Logo"
        style={{
          height: '64px',
          width: 'auto',
          objectFit: 'contain',
        }}
      />
      <div>
        <h1 className="welcome-title">IRIS</h1>
        <p style={{ fontSize: '0.75rem', color: 'var(--enbd-blue)', fontWeight: 500, letterSpacing: '0.1em', textTransform: 'uppercase', textAlign: 'center', marginTop: '0.2rem' }}>
          Investor Relations Intelligence
        </p>
      </div>

      <p className="welcome-subtitle" style={{ fontSize: '0.85rem', maxWidth: '380px' }}>
        Ask questions about Emirates NBD&apos;s investor presentations.
        Responses are grounded strictly in validated source evidence.
      </p>

      {!backendLive && (
        <div style={{
          maxWidth: 480, padding: '0.75rem 1rem',
          background: 'var(--enbd-blue-muted)',
          border: '1px solid var(--enbd-blue-border)',
          borderRadius: 'var(--radius-md)',
          fontSize: '0.75rem', color: 'var(--text-muted)', lineHeight: 1.6,
          textAlign: 'left',
          marginTop: '1rem',
        }}>
          <span style={{ color: 'var(--enbd-blue)', fontWeight: 700 }}>Evidence service starting</span> —
          IRIS will continue serving validated cached Investor Relations answers while the live retrieval service warms up.
        </div>
      )}
    </div>
  );
}

/* ── Main Response Card ── */
function IRResponseCard({
  response, onOpenPage,
}: {
  response: ChatResponse;
  onOpenPage: (docName: string, page: number) => void;
}) {
  const execSummary = response.executive_summary ?? '';

  const sources = response.sources.map(s => ({
    id: s.id,
    docName: s.doc_name ?? '',
    page: s.page,
    support: s.support,
  }));

  const kpis = response.financial_kpis.map(k => ({
    metric: k.metric,
    current: k.current,
    previous: k.previous,
    change: k.change,
    interpretation: k.interpretation,
    direction: (k.direction ?? 'neutral') as 'positive' | 'negative' | 'neutral',
    period: k.period,
    value: k.value,
  }));

  const driversSum = response.key_drivers_summary ?? '';

  const drivers = response.key_drivers.map(d => ({ title: d.title, detail: d.detail }));

  const visuals = response.visual_evidence.map(v => {
    const firstSrc = sources[0];
    const rawDocId = firstSrc
      ? firstSrc.docName.toLowerCase().replace(/ /g, '_').replace(/-/g, '_')
      : 'emiratesnbd_investor_presentation_2026_q1';
    const finalDocId = (rawDocId.includes('emirates') && rawDocId.includes('nbd') && rawDocId.includes('2026') && rawDocId.includes('q1'))
      ? 'emiratesnbd_investor_presentation_2026_q1'
      : rawDocId;

    const imageUrl = normalizePageImageUrl(v.image_url, finalDocId, v.page);

    return {
      id: v.id ?? `v-${v.page}`,
      alt: v.alt ?? `Page ${v.page}`,
      caption: v.alt ?? `Page ${v.page}`,
      page: v.page,
      image_url: imageUrl,
    };
  });

  return (
    <div className="response-card" style={{ maxWidth: '860px', width: '100%' }}>
      {/* IRIS header */}
      <div style={{ display: 'flex', alignItems: 'center', gap: '0.625rem', padding: '0.7rem 1.25rem 0' }}>
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img
          src="/Emirates NBD Bank Logo.png"
          alt="Emirates NBD Logo"
          style={{
            height: '18px',
            width: 'auto',
            objectFit: 'contain',
          }}
        />
        <span style={{ fontSize: '0.72rem', color: 'var(--text-muted)', fontWeight: 500 }}>
          IRIS · IR Intelligence
        </span>
      </div>

      {/* 1. Executive Summary — always expanded */}
      <ExecutiveSummary text={execSummary} />

      {/* 2-3. Accordions — collapsed by default */}
      <div style={{ display: 'flex', flexDirection: 'column', gap: '2px', padding: '0 0.5rem 0.75rem' }}>
        <KeyDriversAccordion summary={driversSum} drivers={drivers} kpis={kpis} />
        <SourceVisualEvidenceAccordion
          visuals={visuals}
          onOpenPage={page => onOpenPage(sources[0]?.docName ?? '', page)}
        />
      </div>

      {/* 4. Sources & Footnotes — now at the end */}
      <SourcesFootnotes
        sources={sources}
        onOpenPage={(docName, page) => onOpenPage(docName, page)}
      />
    </div>
  );
}

/* ── Main Workspace ── */
export function ResponseWorkspace({
  onOpenPage,
  onQuestionAsked,
  triggeredQuestion,
  onClearTriggeredQuestion,
  selectedDocIds,
}: ResponseWorkspaceProps) {
  const [messages, setMessages] = React.useState<Message[]>([]);
  const [isLoading, setIsLoading] = React.useState(false);
  const [backendLive, setBackendLive] = React.useState(false);
  const messagesEndRef = React.useRef<HTMLDivElement>(null);
  const showWelcome = messages.length === 0;

  // Check backend health on mount
  React.useEffect(() => {
    checkBackendHealth().then(setBackendLive);
    const interval = setInterval(() => checkBackendHealth().then(setBackendLive), 15000);
    return () => clearInterval(interval);
  }, []);

  React.useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const handleQuestion = React.useCallback(async (question: string) => {
    const qId = Date.now().toString();
    setMessages(prev => [...prev, { id: qId, type: 'question', content: question }]);
    setIsLoading(true);
    onQuestionAsked?.(question);

    const isOutOfScope = OUT_OF_SCOPE_PATTERNS.some(p => p.test(question));
    if (isOutOfScope) {
      await new Promise(r => setTimeout(r, 400));
      setMessages(prev => [...prev, { id: Date.now().toString(), type: 'unsupported', content: question }]);
      setIsLoading(false);
      return;
    }

    try {
      // Attempt the backend on every submit. The health check is only a UI hint,
      // and can be stale during startup or after a backend restart.
      const response = await submitQuestion(question, selectedDocIds);
      setBackendLive(true);

      if (response.response_type === 'unsupported') {
        setMessages(prev => [...prev, { id: Date.now().toString(), type: 'unsupported', content: question }]);
      } else if (response.response_type === 'insufficient') {
        setMessages(prev => [...prev, { id: Date.now().toString(), type: 'insufficient', content: question }]);
      } else {
        setMessages(prev => [...prev, { id: Date.now().toString(), type: 'ir-response', content: question, response }]);
      }
    } catch (err) {
      console.error('Chat error:', err);
      setBackendLive(false);
      setMessages(prev => [...prev, { id: Date.now().toString(), type: 'insufficient', content: question }]);
    } finally {
      setIsLoading(false);
    }
  }, [onQuestionAsked, selectedDocIds]);

  React.useEffect(() => {
    if (triggeredQuestion) {
      queueMicrotask(() => {
        handleQuestion(triggeredQuestion);
      });
      onClearTriggeredQuestion?.();
    }
  }, [triggeredQuestion, onClearTriggeredQuestion, handleQuestion]);

  return (
    <div className="app-main">
      {showWelcome ? (
        <div style={{ flex: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
          <WelcomeScreen backendLive={backendLive} />
        </div>
      ) : (
        <div className="messages-scroll">
          <div className="messages-inner" style={{
            maxWidth: '900px',
            width: '100%',
            display: 'flex',
            flexDirection: 'column',
            gap: '1.25rem',
            paddingBottom: '1.5rem',
          }}>
            {messages.map(msg => {
              if (msg.type === 'question') {
                return <div key={msg.id} className="question-bubble fade-in-up">{msg.content}</div>;
              }
              if (msg.type === 'unsupported') {
                return (
                  <div key={msg.id} className="fade-in-up" style={{ maxWidth: '860px', width: '100%' }}>
                    <UnsupportedRequest question={msg.content} onSubmit={handleQuestion} />
                  </div>
                );
              }
              if (msg.type === 'insufficient') {
                return (
                  <div key={msg.id} className="fade-in-up" style={{ maxWidth: '860px', width: '100%' }}>
                    <InsufficientEvidence question={msg.content} onSubmit={handleQuestion} />
                  </div>
                );
              }
              if (msg.type === 'ir-response' && msg.response) {
                return (
                  <IRResponseCard
                    key={msg.id}
                    response={msg.response}
                    onOpenPage={onOpenPage}
                  />
                );
              }
              return null;
            })}
            {isLoading && <ThinkingIndicator />}
            <div ref={messagesEndRef} />
          </div>
        </div>
      )}

      <QuestionInput
        onSubmit={handleQuestion}
        isLoading={isLoading}
        showWelcome={showWelcome}
        onSampleQuestion={handleQuestion}
      />
    </div>
  );
}
