import React, { useState, useEffect, useRef } from 'react';
import { useAgent } from '../contexts/AgentContext';
import ReportRenderer from './ReportRenderer';
import {
  Box,
  Typography,
  IconButton,
  Avatar,
  Paper,
  TextField,
  InputAdornment,
  List,
  ListItem,
  ListItemAvatar,
  Chip,
} from '@mui/material';
import SendIcon from '@mui/icons-material/Send';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
import { jsPDF } from 'jspdf';
import {
  Document,
  Packer,
  Paragraph,
  ImageRun,
  Header as DocxHeader,
  AlignmentType,
  HeadingLevel,
  Table as DocxTable,
  TableRow as DocxTableRow,
  TableCell as DocxTableCell,
  WidthType,
  TextRun,
  BorderStyle,
} from 'docx';
interface ChatInterfaceProps {
  onClose?: () => void;
}

const ChatInterface: React.FC<ChatInterfaceProps> = ({ onClose }) => {
  const { selectedAgent, setSelectedAgent } = useAgent();
  type QuickReplyButton = { title: string; payload: string };
  type CustomMultiSelect = {
    type: 'multi_select_chips';
    options: string[];
    columns?: number;
    hint?: string;
    selections?: string[]; // maintained client-side
  };

  // Branding palette + tokens inspired by your screenshot
  const BRAND = {
    gradientFrom: '#FF6B00',
    gradientTo: '#FF3D00',
    headerBg: 'linear-gradient(135deg, #FF6B00 0%, #FF3D00 100%)',
    headerShadow: '0 10px 24px rgba(255, 80, 0, 0.25)',
    windowBg: '#F6F7FB',
    surface: '#FFFFFF',
    border: '#FFE0D1',
    botBubble: '#FFFFFF',
    userBubble: '#FFE9DF',
    userText: '#7A3D2B',
    inputBg: '#FFF4EE',
    inputBorder: '#FFC9B3',
    placeholder: '#9C6B5E',
    sendBtn: '#FA8C6A',
    sendBtnHover: '#FF7A50',
    chipBg: '#FFE4D3',
    chipText: '#7A3D2B',
  };

  // Helper to push a bot notice message after an operation completes
  const pushBotNotice = (text: string) =>
    setMessages(prev => [...prev, { sender: 'bot', text }]);

  type ChatMessage = {
    sender: 'user' | 'bot';
    text?: string;
    buttons?: QuickReplyButton[];
    custom?: CustomMultiSelect;
    json_message?: any; // pass-through for backend control messages
  };

  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [inputValue, setInputValue] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const chatContainerRef = useRef<HTMLDivElement>(null);
  const lastReportRef = useRef<HTMLDivElement | null>(null);
  const reportRefs = useRef<Map<number, HTMLDivElement>>(new Map());
  // Unique sender per agent session to avoid reusing old Rasa tracker state
  const senderRef = useRef<string>('');
  // Track previous and last REST responses so we can download the prior one on demand
  const lastResponseRef = useRef<any>(null);
  const prevResponseRef = useRef<any>(null);

  // Static public paths for logos (put files in /public)
  const YUGEN_LOGO_SRC = '/yugensys.png';
  const BIZ_LOGO_SRC = '/BizInsaights.png'; // NOTE: fixed spelling
  // Initialize a stable sender id once
  useEffect(() => {
    if (!senderRef.current) {
      senderRef.current =
        (crypto as any)?.randomUUID?.() ? `web-${(crypto as any).randomUUID()}` : `web-${Math.random().toString(36).slice(2, 10)}`;
    }
  }, []);
  // Show a "thinking..." message when loading
  useEffect(() => {
    if (isLoading) {
      const loadingText = selectedAgent?.id === 'lexa-legal' 
        ? 'Lexa is thinking...' 
        : 'BizInsights is thinking...';
      
      setMessages(prev => {
        const alreadyShown = prev.some(m => m.text === loadingText);
        if (alreadyShown) return prev;
        return [...prev, { sender: 'bot', text: loadingText }];
      });
    } else {
      setMessages(prev => prev.filter(m => 
        m.text !== 'BizInsights is thinking...' && 
        m.text !== 'Lexa is thinking...'
      ));
    }
  }, [isLoading, selectedAgent]);  

  // Util: download an object as a .json file
  const downloadJson = (obj: any, filename?: string) => {
    try {
      const blob = new Blob([JSON.stringify(obj, null, 2)], { type: 'application/json' });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = filename || `response-${new Date().toISOString().slice(0, 19).replace(/[:T]/g, '-')}.json`;
      document.body.appendChild(link);
      link.click();
      link.remove();
      URL.revokeObjectURL(url);
      sendMessage('/research_complete');
      pushBotNotice('✅ JSON file downloaded');
    } catch (e) {
      console.error('[JSON]Failed to download JSON: ', e);
    }
  };

  // ---- PDF: helpers (fetch + downscale) ----
  const fetchAsDataURL = async (src: string): Promise<string> => {
    const res = await fetch(src, { credentials: 'include', cache: 'force-cache' });
    if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText} for ${src}`);
    const blob = await res.blob();
    return await new Promise<string>((resolve) => {
      const reader = new FileReader();
      reader.onloadend = () => resolve(reader.result as string);
      reader.readAsDataURL(blob);
    });
  };

  const downscaleDataURL = async (
    dataUrl: string,
    maxEdgePx: number,
    mime: 'image/jpeg' | 'image/png',
    quality: number
  ): Promise<string> => {
    const img = await new Promise<HTMLImageElement>((resolve, reject) => {
      const i = new Image();
      i.onload = () => resolve(i);
      i.onerror = () => reject(new Error('Image decode failed'));
      i.src = dataUrl;
    });

    const naturalW = (img as any).naturalWidth || img.width;
    const naturalH = (img as any).naturalHeight || img.height;
    const longest = Math.max(naturalW, naturalH);
    const scale = longest > maxEdgePx ? maxEdgePx / longest : 1;
    const w = Math.max(1, Math.round(naturalW * scale));
    const h = Math.max(1, Math.round(naturalH * scale));

    const canvas = document.createElement('canvas');
    canvas.width = w;
    canvas.height = h;
    const ctx = canvas.getContext('2d');
    if (!ctx) throw new Error('Canvas 2D context unavailable');

    if (mime === 'image/jpeg') {
      ctx.fillStyle = '#ffffff';
      ctx.fillRect(0, 0, w, h);
    }
    ctx.drawImage(img, 0, 0, w, h);
    return canvas.toDataURL(mime, quality);
  };

  // --------- Rasa helpers (NEW) ----------
  // Map Rasa REST payload to our ChatMessage array
  const mapRasaToMessages = (data: any[]): ChatMessage[] => {
    if (!Array.isArray(data)) return [];
    return data
      .map((m: any): ChatMessage | null => {
        let text = typeof m?.text === 'string' ? m.text : undefined;
        const buttons = Array.isArray(m?.buttons)
          ? m.buttons
            .filter((b: any) => typeof b?.title === 'string' && typeof b?.payload === 'string')
            .map((b: any) => ({ title: b.title as string, payload: b.payload as string }))
          : undefined;

        // Pass-through known custom blocks
        let custom: ChatMessage['custom'] = undefined;
        if (m?.custom && typeof m.custom === 'object' && m.custom.type === 'multi_select_chips') {
          const opts = Array.isArray(m.custom.options)
            ? m.custom.options.filter((o: any) => typeof o === 'string')
            : [];
          custom = {
            type: 'multi_select_chips',
            options: opts,
            columns: typeof m.custom.columns === 'number' ? m.custom.columns : undefined,
            hint: typeof m.custom.hint === 'string' ? m.custom.hint : undefined,
            selections: [],
          };
        }

        // Control messages
        let json_message = m?.json_message;
        if (!json_message && m?.custom && typeof m.custom === 'object' && typeof m.custom.action === 'string') {
          json_message = m.custom;
        }
        const action = json_message?.action;
        if (action === 'json:download' || action === 'pdf:download' || action === 'docx:download') {
          text = undefined; // suppress bubble for control actions
        }

        if (!text && (!buttons || buttons.length === 0) && !custom && !json_message) return null;
        return { sender: 'bot', text, buttons, custom, json_message };
      })
      .filter(Boolean) as ChatMessage[];
  };


  // ---- PDF: renderer with logos + selectable text ----
  const generateReportPdf = async ({
    content,
    title,
    yugenLogoSrc = YUGEN_LOGO_SRC,
    bizLogoSrc = BIZ_LOGO_SRC,
    logoMime = 'image/jpeg' as 'image/jpeg' | 'image/png',
    maxLogoEdgePx = 600,
    jpegQuality = 0.82,
  }: {
    content: string;
    title?: string;
    yugenLogoSrc?: string;
    bizLogoSrc?: string;
    logoMime?: 'image/jpeg' | 'image/png';
    maxLogoEdgePx?: number;
    jpegQuality?: number;
  }): Promise<string> => {
    console.info('[PDF] Generating...', { yugenLogoSrc, bizLogoSrc, logoMime });

    const doc = new jsPDF({ unit: 'mm', format: 'a4', compress: true });
    const pageWidth = doc.internal.pageSize.getWidth();
    const pageHeight = doc.internal.pageSize.getHeight();
    const margin = 15;
    const logoHeight = 15; // mm
    const logoWidth = 40;  // mm
    const contentWidth = pageWidth - 2 * margin;

    // Title: derive from first markdown header if not provided
    const derivedTitle = (() => {
      const firstHeader = (content || '')
        .split('\n')
        .map(s => s.trim())
        .find(s => s.startsWith('# '));
      return title || (firstHeader ? firstHeader.replace(/^#\s+/, '') : 'Report');
    })();


    // Load + downscale logos
    let yugenDataUrl: string | null = null;
    let bizDataUrl: string | null = null;
    try {
      const yugenWithCacheBust = `${yugenLogoSrc}?t=${Date.now()}`;
      const yugenRaw = await fetchAsDataURL(yugenWithCacheBust);
      yugenDataUrl = await downscaleDataURL(yugenRaw, maxLogoEdgePx, 'image/png', 1.0);
    } catch (e) {
      console.warn('[PDF] Yugen logo load failed, will skip:', yugenLogoSrc, e);
    }
    try {
      const bizWithCacheBust = `${bizLogoSrc}?t=${Date.now()}`;
      const bizRaw = await fetchAsDataURL(bizWithCacheBust);
      bizDataUrl = await downscaleDataURL(bizRaw, maxLogoEdgePx, 'image/png', 1.0);
    } catch (e) {
      console.warn('[PDF] Biz logo load failed, will skip:', bizLogoSrc, e);
    }

    const YUGEN_ALIAS = 'YUGEN_LOGO';
    const BIZ_ALIAS = 'BIZ_LOGO';
    let embeddedOnce = false;
    let cursorY = margin + logoHeight + 24;
    const baseLine = 6; // mm baseline leading

    const addHeader = () => {
      const fmt = logoMime === 'image/png' ? 'PNG' : 'JPEG';
      if (yugenDataUrl) {
        if (!embeddedOnce) {
          doc.addImage(yugenDataUrl, fmt, margin, margin, logoWidth, logoHeight, YUGEN_ALIAS);
        } else {
          doc.addImage(YUGEN_ALIAS, fmt, margin, margin, logoWidth, logoHeight);
        }
      }
      if (bizDataUrl) {
        const x = pageWidth - margin - logoWidth;
        if (!embeddedOnce) {
          doc.addImage(bizDataUrl, fmt, x, margin, logoWidth, logoHeight, BIZ_ALIAS);
        } else {
          doc.addImage(BIZ_ALIAS, fmt, x, margin, logoWidth, logoHeight);
        }
      }
      embeddedOnce = true;
      doc.setDrawColor(200);
      doc.setLineWidth(0.3);
      doc.line(margin, margin + logoHeight + 4, pageWidth - margin, margin + logoHeight + 4);
    };

    const ensurePage = (nextBlockHeight = 0) => {
      if (cursorY + nextBlockHeight > pageHeight - margin) {
        doc.addPage();
        addHeader();
        cursorY = margin + logoHeight + 10;
      }
    };

    // First page header + title
    addHeader();
    doc.setFont('helvetica', 'bold');
    doc.setFontSize(18);
    doc.text(derivedTitle, pageWidth / 2, margin + logoHeight + 14, { align: 'center' });
    doc.setFont('helvetica', 'normal');
    doc.setFontSize(12);

    // Light markdown handling
    const lines = (content || '').split('\n');
    let inCode = false;
    const codeLines: string[] = [];

    const flushCode = () => {
      if (!inCode || codeLines.length === 0) return;
      doc.setFont('courier', 'normal');
      const lh = 5;
      for (const cl of codeLines) {
        const wrapped = doc.splitTextToSize(cl, contentWidth);
        for (const w of wrapped) {
          ensurePage(lh);
          doc.text(w, margin, cursorY);
          cursorY += lh;
        }
      }
      doc.setFont('helvetica', 'normal');
      inCode = false;
      codeLines.length = 0;
      cursorY += 1.5;
    };

    for (let raw of lines) {
      const line = raw ?? '';
      const t = line.trim();

      if (t.startsWith('```')) {
        if (inCode) flushCode();
        else { inCode = true; codeLines.length = 0; }
        continue;
      }
      if (inCode) { codeLines.push(line); continue; }
      if (!t) { cursorY += baseLine; continue; }

      if (t.startsWith('# ')) {
        const txt = t.replace(/^#\s+/, '');
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(16);
        const wrapped = doc.splitTextToSize(txt, contentWidth);
        ensurePage(baseLine * wrapped.length + 4);
        for (const w of wrapped) { doc.text(w, margin, cursorY); cursorY += baseLine; }
        cursorY += 2;
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(12);
        continue;
      }
      if (t.startsWith('## ')) {
        const txt = t.replace(/^##\s+/, '');
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(14);
        const wrapped = doc.splitTextToSize(txt, contentWidth);
        ensurePage(baseLine * wrapped.length + 2);
        for (const w of wrapped) { doc.text(w, margin, cursorY); cursorY += baseLine; }
        cursorY += 1;
        doc.setFont('helvetica', 'normal');
        doc.setFontSize(12);
        continue;
      }
      if (t.startsWith('### ')) {
        const txt = t.replace(/^###\s+/, '');
        doc.setFont('helvetica', 'bold');
        doc.setFontSize(12);
        const wrapped = doc.splitTextToSize(txt, contentWidth);
        ensurePage(baseLine * wrapped.length + 1);
        for (const w of wrapped) { doc.text(w, margin, cursorY); cursorY += baseLine; }
        doc.setFont('helvetica', 'normal');
        continue;
      }

      if (/^(\* |- |• )/.test(t)) {
        const bulletText = t.replace(/^(\* |- |• )/, '');
        const bulletIndent = 6;
        const textX = margin + bulletIndent;
        const wrapWidth = contentWidth - bulletIndent;
        const wrapped = doc.splitTextToSize(bulletText, wrapWidth);
        ensurePage(baseLine * wrapped.length);
        doc.text('•', margin + 1, cursorY);
        doc.text(wrapped[0], textX, cursorY);
        cursorY += baseLine;
        for (let k = 1; k < wrapped.length; k++) {
          ensurePage(baseLine);
          doc.text(wrapped[k], textX, cursorY);
          cursorY += baseLine;
        }
        continue;
      }

      const wrapped = doc.splitTextToSize(line, contentWidth);
      ensurePage(baseLine * wrapped.length);
      for (const w of wrapped) { doc.text(w, margin, cursorY); cursorY += baseLine; }
    }
    if (inCode) flushCode();

    const filename = `report-${new Date().toISOString().replace(/[:.]/g, '-')}.pdf`;

    // 🟢 Trigger file download
    doc.save(filename);
    // Reuse your pipeline so the UI updates and isLoading is handled
    await sendMessage('/research_complete');

    return filename;
  };

  // ---- DOCX: Generator with logos + selectable text ----
  const generateReportDocx = async ({
    content,
    title,
    yugenLogoSrc = YUGEN_LOGO_SRC,
    bizLogoSrc = BIZ_LOGO_SRC,
  }: {
    content: string;
    title?: string;
    yugenLogoSrc?: string;
    bizLogoSrc?: string;
  }): Promise<string> => {
    console.info('[DOCX] Generating text-based document...');

    // Helper to fetch image as ArrayBuffer for the docx library
    const fetchImageAsArrayBuffer = async (src: string): Promise<ArrayBuffer | null> => {
      try {
        const res = await fetch(src, { credentials: 'include', cache: 'force-cache' });
        if (!res.ok) throw new Error(`HTTP ${res.status} for ${src}`);
        return await res.arrayBuffer();
      } catch (e) {
        console.warn(`[DOCX] Image load failed for ${src}:`, e);
        return null;
      }
    };

    const [yugenLogoBuffer, bizLogoBuffer] = await Promise.all([
      fetchImageAsArrayBuffer(yugenLogoSrc),
      fetchImageAsArrayBuffer(bizLogoSrc),
    ]);

    const headerChildren: (Paragraph | DocxTable)[] = [];
    if (yugenLogoBuffer && bizLogoBuffer) {
      headerChildren.push(
        new DocxTable({
          width: { size: '100%', type: WidthType.PERCENTAGE },
          columnWidths: [2500, 5000, 2500],
          borders: { top: { style: 'none' }, bottom: { style: 'none' }, left: { style: 'none' }, right: { style: 'none' } },
          rows: [
            new DocxTableRow({
              children: [
                new DocxTableCell({
                  children: [new Paragraph({
                    children: [new ImageRun({
                      data: yugenLogoBuffer,
                      transformation: { width: 160, height: 60 },
                      type: 'png', // or 'jpeg' based on your image type
                    })]
                  })],
                  borders: { top: { style: 'none' }, bottom: { style: 'none' }, left: { style: 'none' }, right: { style: 'none' } },
                }),
                new DocxTableCell({ children: [new Paragraph('')], borders: { top: { style: 'none' }, bottom: { style: 'none' }, left: { style: 'none' }, right: { style: 'none' } } }),
                new DocxTableCell({
                  children: [new Paragraph({
                    alignment: AlignmentType.RIGHT, children: [new ImageRun({
                      data: bizLogoBuffer,
                      transformation: { width: 160, height: 60 },
                      type: 'png', // or 'jpeg' based on your image type
                    })]
                  })],
                  borders: { top: { style: 'none' }, bottom: { style: 'none' }, left: { style: 'none' }, right: { style: 'none' } },
                }),
              ],
            }),
          ],
        })
      );
    }
    headerChildren.push(new Paragraph({
      style: 'header', border: {
        top: { style: BorderStyle.SINGLE },
        bottom: { style: BorderStyle.SINGLE },
        left: { style: BorderStyle.SINGLE },
        right: { style: BorderStyle.SINGLE }
      }
    }));

    const derivedTitle = title || (content || '').split('\n').map(s => s.trim()).find(s => s.startsWith('# '))?.replace(/^#\s+/, '') || 'Report';

    const bodyParagraphs: Paragraph[] = [
      new Paragraph({ text: derivedTitle, heading: HeadingLevel.TITLE, alignment: AlignmentType.CENTER }),
      new Paragraph({ text: '' }), // Spacer
    ];

    (content || '').split('\n').forEach(line => {
      const t = line.trim();
      if (t.startsWith('### ')) {
        bodyParagraphs.push(new Paragraph({ text: t.replace(/^###\s+/, ''), heading: HeadingLevel.HEADING_3 }));
      } else if (t.startsWith('## ')) {
        bodyParagraphs.push(new Paragraph({ text: t.replace(/^##\s+/, ''), heading: HeadingLevel.HEADING_2 }));
      } else if (t.startsWith('# ') && t.replace(/^#\s+/, '') !== derivedTitle) {
        bodyParagraphs.push(new Paragraph({ text: t.replace(/^#\s+/, ''), heading: HeadingLevel.HEADING_1 }));
      } else if (/^(\* |- |• )/.test(t)) {
        bodyParagraphs.push(new Paragraph({ text: t.replace(/^(\* |- |• )/, ''), bullet: { level: 0 } }));
      } else {
        const runs = (line.split(/(\*\*.*?\*\*|\*.*?\*)/g).filter(Boolean)).map(part => {
          if (part.startsWith('**') && part.endsWith('**')) return new TextRun({ text: part.slice(2, -2), bold: true });
          if (part.startsWith('*') && part.endsWith('*')) return new TextRun({ text: part.slice(1, -1), italics: true });
          return new TextRun(part);
        });
        bodyParagraphs.push(new Paragraph({ children: runs }));
      }
    });

    const doc = new Document({
      sections: [{ headers: { default: new DocxHeader({ children: headerChildren }) }, children: bodyParagraphs }],
    });

    const filename = `report-${new Date().toISOString().replace(/[:.]/g, '-')}.docx`;
    const blob = await Packer.toBlob(doc);
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(link.href);

    // Notify RASA that the research step is complete
    await sendMessage('/research_complete');

    return filename;
  };

  const sendMessage = async (outgoing: string) => {
    if (!outgoing.trim()) return;
    setIsLoading(true);
    try {
      const requestBody = {
        sender: senderRef.current || 'web-user',
        message: outgoing,
        metadata: {
          agent: selectedAgent?.id === 'lexa-legal' ? 'lexa' : 'biz'
        }
      };
      
      const res = await fetch(`https://devyugensys-rasa-bizinsight.hf.space/webhooks/rest/webhook`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(requestBody),
      });

      if (!res.ok) throw new Error(`Backend error: ${res.status} ${res.statusText}`);
      const data = await res.json();
      prevResponseRef.current = lastResponseRef.current;
      lastResponseRef.current = data;

      const botMessages: ChatMessage[] = Array.isArray(data)
        ? data
          .map((m: any): ChatMessage | null => {
            let text = typeof m?.text === 'string' ? m.text : undefined;
            const buttons = Array.isArray(m?.buttons)
              ? m.buttons
                .filter((b: any) => typeof b?.title === 'string' && typeof b?.payload === 'string')
                .map((b: any) => ({ title: b.title as string, payload: b.payload as string }))
              : undefined;
            let custom: ChatMessage['custom'] = undefined;
            if (m?.custom && typeof m.custom === 'object' && m.custom.type === 'multi_select_chips') {
              const opts = Array.isArray(m.custom.options) ? m.custom.options.filter((o: any) => typeof o === 'string') : [];
              custom = {
                type: 'multi_select_chips',
                options: opts,
                columns: typeof m.custom.columns === 'number' ? m.custom.columns : undefined,
                hint: typeof m.custom.hint === 'string' ? m.custom.hint : undefined,
                selections: [],
              };
            }
            let json_message = m?.json_message;
            if (!json_message && m?.custom && typeof m.custom === 'object' && typeof m.custom.action === 'string') {
              json_message = m.custom;
            }
            const action = json_message?.action;
            if (action === 'json:download' || action === 'pdf:download' || action === 'docx:download') {
              text = undefined;
            }
            if (!text && (!buttons || buttons.length === 0) && !custom && !json_message) return null;
            return { sender: 'bot', text, buttons, custom, json_message } as ChatMessage;
          })
          .filter(Boolean) as ChatMessage[]
        : [];

      if (botMessages.length > 0) {
        const visibleMessages = botMessages.filter(
          (m) => !!(m.text || (m.buttons && m.buttons.length > 0) || m.custom)
        );
        const combined = [...messages, ...visibleMessages];
        setMessages(prev => [...prev, ...visibleMessages]);

        const pdfAction = botMessages.find(m => (m as any).json_message?.action === 'pdf:download');
        const docxAction = botMessages.find(m => (m as any).json_message?.action === 'docx:download');
        const jsonAction = botMessages.find(m => (m as any).json_message?.action === 'json:download');

        if (pdfAction || docxAction || jsonAction) {
          // New, more robust logic to find the last substantive report message,
          // ignoring short confirmation or prompt messages.
          const findLastReportText = (messageList: ChatMessage[]): string => {
            // Search backwards from the end of the message list.
            for (let i = messageList.length - 1; i >= 0; i--) {
              const msg = messageList[i];
              if (msg.sender === 'bot' && msg.text) {
                // Heuristic: A real report contains markdown headers ('#') or is reasonably long.
                // This reliably filters out short status updates like "✅ PDF downloaded...".
                const isLikelyReport = msg.text.includes('Report') || msg.text.length > 200;
                if (isLikelyReport) {
                  return msg.text; // Found the report content
                }
              }
            }
            return ''; // No report found
          };

          const targetText = findLastReportText(combined);

          if (!targetText.trim()) {
            pushBotNotice('❌ Could not find report content to download.');
          } else {
            if (pdfAction) {
              try {
                const filename = await generateReportPdf({ content: targetText });
                pushBotNotice(`✅ PDF downloaded: ${filename}`);
              } catch (e) {
                console.error('[PDF] Failed to generate:', e);
                pushBotNotice('❌ Failed to generate PDF file.');
              }
            }

            if (docxAction) {
              try {
                const filename = await generateReportDocx({ content: targetText });
                pushBotNotice(`✅ DOCX downloaded: ${filename}`);
              } catch (e) {
                console.error('[DOCX] Failed to generate:', e);
                pushBotNotice('❌ Failed to generate DOCX file.');
              }
            }
            if (jsonAction) {
              try {
                // Create a proper JSON object with the report content
                const jsonContent = {
                  report: targetText,
                  generatedAt: new Date().toISOString()
                };
                // Call downloadJson with the JSON object and let it handle the rest
                downloadJson(jsonContent, `report-${new Date().toISOString().slice(0, 10)}.json`);
                
              } catch (e) {
                console.error('[JSON] Failed to generate:', e);
                pushBotNotice('❌ Failed to generate JSON file.');
              }
            }
          }
        }
        // if (pdfAction || docxAction) {
        //   const botTextIdxs = combined
        //     .map((m, idx) => ({ m, idx }))
        //     .filter(x => x.m.sender === 'bot' && !!x.m.text)
        //     .map(x => x.idx);
        //   const targetIdx =
        //     botTextIdxs.length >= 2
        //       ? botTextIdxs[botTextIdxs.length - 2]
        //       : botTextIdxs[botTextIdxs.length - 1];

        //   const targetMsg = targetIdx !== undefined ? combined[targetIdx] : undefined;
        //   const targetText = targetMsg?.text || '';

        //   if (pdfAction) {
        //     if (!targetText.trim()) {
        //       await startDownload();
        //     } else {
        //       try {
        //         const filename = await generateReportPdf({ content: targetText });
        //         pushBotNotice(`✅ PDF downloaded: ${filename}`);
        //       } catch (e) {
        //         console.error('[PDF] Failed to generate:', e);
        //       }
        //     }
        //   }

        //   if (docxAction) {
        //     if (!targetText.trim()) {
        //       pushBotNotice('❌ Could not find report content to download.');
        //     } else {
        //       try {
        //         // Use the new text-based generator
        //         const filename = await generateReportDocx({ content: targetText });
        //         pushBotNotice(`✅ DOCX downloaded: ${filename}`);
        //       } catch (e) {
        //         console.error('[DOCX] Failed to generate:', e);
        //         pushBotNotice('❌ Failed to generate DOCX file.');
        //       }
        //     }
        //   }
        // }
      }
    } catch (error) {
      console.error('[DEBUG] sendMessage error:', error);
      setMessages(prev => [...prev, { text: '❌ Something went wrong.', sender: 'bot' }]);
    } finally {
      setIsLoading(false);
    }
  };

  const handleSendMessage = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!inputValue.trim()) return;
    const userMessage = inputValue.trim();
    setMessages(prev => [...prev, { text: userMessage, sender: 'user' }]);
    setInputValue('');
    await sendMessage(userMessage);
  };

  const handleQuickReply = async (btn: QuickReplyButton) => {
    const lastMultiIndex = [...messages]
      .map((m, idx) => ({ m, idx }))
      .reverse()
      .find(item => item.m.custom?.type === 'multi_select_chips')?.idx;

    const lastMulti = lastMultiIndex !== undefined ? messages[lastMultiIndex] : undefined;
    const selections = lastMulti?.custom?.selections ?? [];

    if (btn.payload.startsWith('/')) {
      if (selections.length > 0 && btn.payload.includes('continue')) {
        const payloadWithSelections = `${btn.payload}${JSON.stringify({ selections })}`;
        setMessages(prev => [
          ...prev,
          { text: `${btn.title}\n${selections.join(', ')}`, sender: 'user' },
        ]);
        await sendMessage(payloadWithSelections);
        return;
      }
    }

    setMessages(prev => [...prev, { text: btn.title, sender: 'user' }]);
    await sendMessage(btn.payload);
  };

  const toggleMultiSelect = (messageIndex: number, option: string) => {
    setMessages(prev => {
      const next = [...prev];
      const msg = next[messageIndex];
      if (!msg?.custom || msg.custom.type !== 'multi_select_chips') return prev;
      const current = new Set(msg.custom.selections || []);
      current.has(option) ? current.delete(option) : current.add(option);
      msg.custom = { ...msg.custom, selections: Array.from(current) };
      next[messageIndex] = { ...msg };
      return next;
    });
  };

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

  // Preload Bizinsight welcome content on first entry
  useEffect(() => {
    if (!selectedAgent) return;
    const isBizInsight = selectedAgent.id === 'rival-lens' || /bizinsight/i.test(selectedAgent.name || '');
    if (!isBizInsight) return;
    if (messages.length > 0) return;

    const welcomeText = "👋 Welcome to Yugensys BizResearch AI Agent!\n\nYour AI-powered business intelligence researcher. Get comprehensive insights on any company in minutes.\n\nWhat company would you like to research today?";
    const buttons = [
      { title: 'Hubspot', payload: '/inform_company{"company_name": "Hubspot"}' },
      { title: 'Zoho', payload: '/inform_company{"company_name": "Zoho"}' },
      { title: 'Salesforce', payload: '/inform_company{"company_name": "Salesforce"}' },
      { title: 'Tesla', payload: '/inform_company{"company_name": "Tesla"}' },
    ];
    const followUpText = 'Or you can Enter company name... 🔍';

    setMessages([
      { sender: 'bot', text: welcomeText, buttons },
      { sender: 'bot', text: followUpText },
    ]);
  }, [selectedAgent]);

  if (!selectedAgent) return null;

  // Determine last bot message with text (rendered in ReportRenderer)
  const lastBotIndex = (() => {
    for (let i = messages.length - 1; i >= 0; i--) {
      const m = messages[i];
      if (m.sender === 'bot' && m.text) return i;
    }
    return -1;
  })();

  return (
    <Box
      sx={{
        position: 'fixed',
        right: { xs: 12, sm: 24 },
        bottom: { xs: 12, sm: 24 },
        width: 'clamp(320px, 36vw, 420px)',
        height: 'clamp(520px, 95dvh, 720px)',
        zIndex: 1300,
        pointerEvents: 'auto',
        bgcolor: 'transparent',
      }}
    >
      {/* Chat window */}
      <Paper
        elevation={0}
        sx={{
          width: '100%',
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          borderRadius: 10,
          overflow: 'hidden',
          boxShadow: BRAND.headerShadow,
          bgcolor: BRAND.windowBg,
        }}
      >
        {/* Header with gradient */}
        <Box
          sx={{
            background: BRAND.headerBg,
            color: '#fff',
            px: 2,
            py: 1.5,
            display: 'flex',
            alignItems: 'center',
            gap: 1.25,
          }}
        >
          <IconButton
            onClick={() => {
              if (onClose) {
                onClose();
              } else {
                setSelectedAgent(null);
              }
            }}
            size="small"
            sx={{
              bgcolor: 'rgba(255,255,255,0.2)',
              color: '#fff',
              '&:hover': {
                bgcolor: 'rgba(255,255,255,0.3)',
                transform: 'translateX(-2px)'
              },
              transition: 'all 0.2s ease',
              width: 32,
              height: 32,
              mr: 1
            }}
          >
            <ArrowBackIcon fontSize="small" />
          </IconButton>
          <Avatar
            sx={{
              width: 28,
              height: 28,
              border: '2px solid rgba(255,255,255,0.35)',
              bgcolor: 'primary.main',
              color: 'white'
            }}
          >
            <AutoAwesomeIcon
              sx={{
                color: '#FF3D00',
                bgcolor: 'white',
                borderRadius: '50%',
                p: 0.8,
                fontSize: 31,
                transition: 'all 0.3s ease',
                '&:hover': {
                  transform: 'scale(1.1)',
                },
              }}
            />
          </Avatar>
          <Box sx={{ flex: 1, overflow: 'hidden' }}>
            <Typography variant="subtitle1" sx={{ fontWeight: 700, lineHeight: 1.1 }}>
              {selectedAgent?.id === 'lexa-legal' ? 'Lexa' : 'BizInsights'} Assistant
            </Typography>
            <Typography variant="caption" sx={{ opacity: 0.9 }}>
              {selectedAgent?.id === 'lexa-legal' 
                ? 'Legal Research Assistant' 
                : 'Competitive Intelligence Assistant'}
            </Typography>
          </Box>

        </Box>

        {/* Conversation area */}
        <Box
          ref={chatContainerRef}
          sx={{
            flex: 1,
            minHeight: 0, // Important for flexbox scrolling
            overflowY: 'auto',
            p: 1.5,
            overscrollBehavior: 'contain',
            bgcolor: BRAND.windowBg,
            '&::-webkit-scrollbar': { width: 8 },
            '&::-webkit-scrollbar-thumb': {
              backgroundColor: '#E5E7EB',
              borderRadius: 8,
            },
          }}
        >
          <List sx={{ width: '100%', py: 0 }}>
            {messages.map((msg, i) => (
              <ListItem
                key={i}
                sx={{
                  justifyContent: msg.sender === 'user' ? 'flex-end' : 'flex-start',
                  alignItems: 'flex-start',
                  px: 0.5,
                }}
              >
                {msg.sender === 'bot' && (
                  <ListItemAvatar sx={{ minWidth: 38, mt: 0.5 }}>
                    <Avatar
                      sx={{
                        width: 28,
                        height: 28,
                        border: `2px solid ${BRAND.border}`,
                        bgcolor: 'primary.main',
                        color: 'white'
                      }}
                    >
                      <AutoAwesomeIcon
                        sx={{
                          color: '#FF3D00',
                          bgcolor: 'white',
                          borderRadius: '50%',
                          p: 0.8,
                          fontSize: 28,
                          transition: 'all 0.3s ease',
                          '&:hover': {
                            transform: 'scale(1.1)',
                          },
                        }}
                      />
                    </Avatar>
                  </ListItemAvatar>
                )}


                <Paper
                  sx={{
                    p: 1.25,
                    px: 1.5,
                    bgcolor: msg.sender === 'user' ? BRAND.userBubble : BRAND.botBubble,
                    borderRadius: 3,
                    boxShadow: '0 4px 14px rgba(0,0,0,0.06)',
                    maxWidth: '85%',
                    position: 'relative',
                    ...(msg.sender === 'user' && { borderTopRightRadius: 4, color: BRAND.userText }),
                    ...(msg.sender === 'bot' && { borderTopLeftRadius: 4 }),
                  }}
                >
                  {msg.sender === 'bot' && msg.text ? (
                    <>
                      <Box sx={{
                        '& > *:not(:last-child)': { mb: 1.5 },
                        '& h1, & h2, & h3, & h4, & h5, & h6': {
                          color: 'primary.main',
                          mt: 2,
                          mb: 1.5
                        },
                        '& pre': {
                          backgroundColor: 'rgba(0,0,0,0.05)',
                          p: 2,
                          borderRadius: 1,
                          overflowX: 'auto'
                        },
                        '& table': {
                          borderCollapse: 'collapse',
                          width: '100%',
                          mb: 2,
                          '& th, & td': {
                            border: '1px solid',
                            borderColor: 'divider',
                            p: 1,
                            textAlign: 'left'
                          },
                          '& th': {
                            backgroundColor: 'action.hover',
                            fontWeight: 'bold'
                          },
                        },
                      }}>
                        <ReportRenderer content={msg.text} />
                      </Box>

                      {msg.buttons && msg.buttons.length > 0 && (
                        <Box sx={{ mt: 1.5, display: 'flex', flexWrap: 'wrap', gap: 1 }}>
                          {msg.buttons.map((btn, idx) => (
                            <Chip
                              key={idx}
                              label={btn.title}
                              onClick={() => handleQuickReply(btn)}
                              sx={{
                                bgcolor: BRAND.chipBg,
                                color: BRAND.chipText,
                                '&:hover': { bgcolor: '#FFD4BB' },
                                cursor: 'pointer',
                              }}
                            />
                          ))}
                        </Box>
                      )}
                    </>
                  ) : (
                    <>
                      {msg.text && (
                        <Typography
                          variant="body2"
                          sx={{ whiteSpace: 'pre-line', lineHeight: 1.5 }}
                          dangerouslySetInnerHTML={{ __html: msg.text.replace(/\n/g, '<br />') }}
                        />
                      )}

                      {msg.buttons && msg.buttons.length > 0 && (
                        <Box sx={{ mt: 1.5, display: 'flex', flexWrap: 'wrap', gap: 1 }}>
                          {msg.buttons.map((btn, idx) => (
                            <Chip
                              key={idx}
                              label={btn.title}
                              onClick={() => handleQuickReply(btn)}
                              sx={{
                                bgcolor: BRAND.chipBg,
                                color: BRAND.chipText,
                                '&:hover': { bgcolor: '#FFD4BB' },
                                cursor: 'pointer',
                              }}
                            />
                          ))}
                        </Box>
                      )}
                    </>
                  )}

                  {/* Multi-select chips (custom payload) */}
                  {msg.custom?.type === 'multi_select_chips' && (
                    <Box sx={{ mt: 1.5 }}>
                      {msg.custom.hint && (
                        <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
                          {msg.custom.hint}
                        </Typography>
                      )}
                      <Box
                        sx={{
                          display: 'grid',
                          gridTemplateColumns: `repeat(${msg.custom?.columns || 2}, minmax(0, 1fr))`,
                          gap: 0.75,
                        }}
                      >
                        {(msg.custom.options || []).map((opt) => {
                          const selected = !!msg.custom?.selections?.includes(opt);
                          return (
                            <Chip
                              key={opt}
                              label={opt}
                              onClick={() => toggleMultiSelect(i, opt)}
                              variant={selected ? 'filled' : 'outlined'}
                              color={selected ? 'primary' : undefined}
                              sx={{
                                borderRadius: 999,
                                width: '100%',
                                justifyContent: 'flex-start',
                                bgcolor: selected ? BRAND.chipBg : 'transparent',
                                borderColor: BRAND.inputBorder,
                                color: BRAND.chipText,
                                '& .MuiChip-label': { whiteSpace: 'normal' },
                                '&:hover': { bgcolor: selected ? '#FFD4BB' : 'transparent' },
                              }}
                            />
                          );
                        })}
                      </Box>
                    </Box>
                  )}
                </Paper>



              </ListItem>
            ))}

            <div ref={messagesEndRef} />
          </List>
        </Box>

        {/* Composer */}
        <Box
          component="form"
          onSubmit={handleSendMessage}
          sx={{
            p: 1.25,
            bgcolor: BRAND.windowBg,
            borderTop: '1px solid #EDF0F5',
            flexShrink: 0,
          }}
        >
          <TextField
            fullWidth
            variant="outlined"
            placeholder="Type here"
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                handleSendMessage(e);
              }
            }}
            multiline
            maxRows={4}
            disabled={isLoading}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end" sx={{ mr: 0.25 }}>
                  <IconButton
                    type="submit"
                    disabled={!inputValue.trim() || isLoading}
                    sx={{
                      bgcolor: BRAND.sendBtn,
                      color: '#fff',
                      width: 40,
                      height: 40,
                      borderRadius: 2,
                      boxShadow: '0 6px 18px rgba(250, 140, 106, 0.35)',
                      '&:hover': { bgcolor: BRAND.sendBtnHover },
                    }}
                    edge="end"
                  >
                    <SendIcon fontSize="small" />
                  </IconButton>
                </InputAdornment>
              ),
              sx: {
                borderRadius: 3,
                bgcolor: BRAND.inputBg,
                '& .MuiOutlinedInput-input::placeholder': {
                  color: BRAND.placeholder,
                  opacity: 1,
                },
                '& .MuiOutlinedInput-notchedOutline': {
                  borderColor: BRAND.inputBorder,
                },
                '&:hover .MuiOutlinedInput-notchedOutline': {
                  borderColor: BRAND.inputBorder,
                },
                '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
                  borderColor: BRAND.sendBtn,
                  borderWidth: 1.5,
                },
              },
            }}
          />
        </Box>
      </Paper>
    </Box>
  );
};

export default ChatInterface;