import { useEffect, useRef, useState } from "react";
import type { AssistantConversationItem } from "../state/types";
import { JsonView } from "./JsonView";
import { PanelFrame } from "./PanelFrame";

interface AssistantPanelProps {
  sessionId: string;
  conversation: AssistantConversationItem[];
  inputValue: string;
  onInputChange: (value: string) => void;
  periodHint: string;
  onPeriodHintChange: (value: string) => void;
  businessContext: string;
  onBusinessContextChange: (value: string) => void;
  useMock: boolean;
  onUseMockChange: (value: boolean) => void;
  onSend: () => Promise<void> | void;
  onClear: () => void;
  busy: boolean;
  statusText: string;
  errorMessage: string;
}

function roleLabel(role: AssistantConversationItem["role"]): string {
  return role === "assistant" ? "Ассистент" : "Вы";
}

function shortTime(iso: string): string {
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) {
    return iso;
  }
  return date.toLocaleTimeString("ru-RU");
}

function stringifyDebug(value: unknown): string {
  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
}

function buildConversationExport(sessionId: string, conversation: AssistantConversationItem[]): string {
  const lines: string[] = [];
  lines.push("# Assistant conversation export");
  lines.push(`session_id: ${sessionId || "n/a"}`);
  lines.push(`exported_at: ${new Date().toISOString()}`);
  lines.push("");

  for (let index = 0; index < conversation.length; index += 1) {
    const item = conversation[index];
    lines.push(`## ${index + 1}. ${item.role}`);
    lines.push(`message_id: ${item.message_id}`);
    lines.push(`created_at: ${item.created_at}`);
    lines.push(`reply_type: ${item.reply_type ?? "n/a"}`);
    if (item.trace_id) {
      lines.push(`trace_id: ${item.trace_id}`);
    }
    lines.push("");
    lines.push(item.text || "(empty)");
    lines.push("");

    if (item.role === "assistant" && item.debug) {
      lines.push("### technical_breakdown_json");
      lines.push("```json");
      lines.push(stringifyDebug(item.debug));
      lines.push("```");
      lines.push("");
    }
  }

  return lines.join("\n");
}

async function copyTextToClipboard(text: string): Promise<boolean> {
  if (navigator.clipboard && window.isSecureContext) {
    try {
      await navigator.clipboard.writeText(text);
      return true;
    } catch {
      // Fall back to legacy path below.
    }
  }

  const textarea = document.createElement("textarea");
  textarea.value = text;
  textarea.setAttribute("readonly", "true");
  textarea.style.position = "fixed";
  textarea.style.opacity = "0";
  textarea.style.pointerEvents = "none";
  document.body.appendChild(textarea);
  textarea.select();

  let copied = false;
  try {
    copied = document.execCommand("copy");
  } catch {
    copied = false;
  } finally {
    document.body.removeChild(textarea);
  }

  return copied;
}

export function AssistantPanel({
  sessionId,
  conversation,
  inputValue,
  onInputChange,
  periodHint,
  onPeriodHintChange,
  businessContext,
  onBusinessContextChange,
  useMock,
  onUseMockChange,
  onSend,
  onClear,
  busy,
  statusText,
  errorMessage
}: AssistantPanelProps) {
  const listRef = useRef<HTMLDivElement | null>(null);
  const copyResetTimerRef = useRef<number | null>(null);
  const [copyState, setCopyState] = useState<"idle" | "success" | "error">("idle");

  useEffect(() => {
    if (listRef.current) {
      listRef.current.scrollTop = listRef.current.scrollHeight;
    }
  }, [conversation, statusText]);

  useEffect(() => {
    return () => {
      if (copyResetTimerRef.current !== null) {
        window.clearTimeout(copyResetTimerRef.current);
      }
    };
  }, []);

  async function handleCopyConversation(): Promise<void> {
    if (conversation.length === 0) {
      return;
    }
    const exportText = buildConversationExport(sessionId, conversation);
    const copied = await copyTextToClipboard(exportText);
    setCopyState(copied ? "success" : "error");

    if (copyResetTimerRef.current !== null) {
      window.clearTimeout(copyResetTimerRef.current);
    }
    copyResetTimerRef.current = window.setTimeout(() => {
      setCopyState("idle");
    }, 2200);
  }

  return (
    <PanelFrame
      title="Режим ассистента"
      subtitle="Диалоговый слой поверх normalizer, маршрутизации и factual retrieval."
      actions={
        <div className="assistant-panel-actions">
          <button
            type="button"
            className="assistant-copy-btn"
            onClick={() => {
              void handleCopyConversation();
            }}
            disabled={conversation.length === 0}
          >
            Скопировать чат
          </button>
          {copyState === "success" ? <span className="assistant-copy-feedback success">Скопировано</span> : null}
          {copyState === "error" ? <span className="assistant-copy-feedback error">Ошибка копирования</span> : null}
          <span className="status-chip">{sessionId ? `session: ${sessionId}` : "новая сессия"}</span>
        </div>
      }
    >
      <div ref={listRef} className="assistant-chat-list">
        {conversation.length === 0 ? (
          <div className="assistant-empty muted">Диалог пуст. Отправьте первый вопрос, чтобы запустить контур ассистента.</div>
        ) : null}
        {conversation.map((item) => (
          <article key={item.message_id} className={`assistant-msg ${item.role}`}>
            <header className="assistant-msg-head">
              <strong>{roleLabel(item.role)}</strong>
              <span>{shortTime(item.created_at)}</span>
            </header>
            <div className="assistant-msg-body">{item.text}</div>
            {item.role === "assistant" && item.debug ? (
              <details className="assistant-debug">
                <summary>Показать технический разбор</summary>
                <JsonView value={item.debug} />
              </details>
            ) : null}
          </article>
        ))}
      </div>

      <div className="assistant-compose">
        <div className="grid-two">
          <label>
            Подсказка по периоду
            <input value={periodHint} onChange={(event) => onPeriodHintChange(event.target.value)} />
          </label>
          <label>
            Бизнес-контекст
            <input value={businessContext} onChange={(event) => onBusinessContextChange(event.target.value)} />
          </label>
        </div>
        <label className="full-width">
          Сообщение
          <textarea
            value={inputValue}
            onChange={(event) => onInputChange(event.target.value)}
            rows={4}
            placeholder="Введите вопрос к данным компании..."
          />
        </label>
        <div className="button-row">
          <label className="checkbox-row">
            <input type="checkbox" checked={useMock} onChange={(event) => onUseMockChange(event.target.checked)} />
            Mock-режим
          </label>
          <button type="button" onClick={() => onSend()} disabled={busy || !inputValue.trim()}>
            {busy ? "Выполняю..." : "Отправить"}
          </button>
          <button type="button" onClick={() => onClear()} disabled={busy && conversation.length === 0}>
            Сбросить сессию
          </button>
        </div>
        {statusText ? <p className="diff-summary">{statusText}</p> : null}
        {errorMessage ? <p className="error-text">{errorMessage}</p> : null}
      </div>
    </PanelFrame>
  );
}
