import React, { useState, useRef, useEffect } from 'react';
import { useEditor } from '@craftjs/core';
import { useEditorConfig } from '../../state/EditorConfigContext';
import { useSitesmith } from '../../hooks/useSitesmith';
import { useApplyAiResponse } from '../../utils/apply-ai-response';
import { summarizeCanvas } from '../../utils/canvas-summary';
import { SitesmithTarget } from '../../state/SitesmithContext';
import { UpgradeBanner } from './UpgradeBanner';
import { ScopeConfirmDialog } from './ScopeConfirmDialog';
import { MessageList } from './MessageList';
import { ChatInput } from './ChatInput';
import { WorkingIndicator } from './WorkingIndicator';
import { SitesmithResponse } from '../../types/sitesmith';
import { Modal } from '../../ui/Modal';

interface Props {
  onClose: () => void;
  /** When set, the chat is biased toward editing this specific node and the AI is
   * instructed to return a `patch` op. The node's serialized tree is sent along. */
  target?: SitesmithTarget | null;
}

export const SitesmithModal: React.FC<Props> = ({ onClose, target }) => {
  const cfg = useEditorConfig();
  const siteId = cfg.whpConfig?.siteId ?? 0;
  const { query } = useEditor();
  const { summary, messages, send, loading, clearHistory } = useSitesmith(siteId);
  const apply = useApplyAiResponse();
  const [busy, setBusy] = useState(false);
  const [pendingReplace, setPendingReplace] = useState<SitesmithResponse | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [confirmClearChat, setConfirmClearChat] = useState(false);
  const clearChatTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => {
    return () => {
      if (clearChatTimeoutRef.current) clearTimeout(clearChatTimeoutRef.current);
    };
  }, []);

  const canChat = summary && (summary.status === 'OK_BONUS' || summary.status === 'OK_MONTHLY');

  const panel:   React.CSSProperties = { background: '#0f0f17', border: '1px solid #27272a', borderRadius: 12, width: 'min(720px, 90vw)', maxHeight: '90vh', display: 'flex', flexDirection: 'column' };
  const header:  React.CSSProperties = { display: 'flex', alignItems: 'center', padding: '14px 18px', borderBottom: '1px solid #27272a', gap: 8 };
  const body:    React.CSSProperties = { flex: 1, padding: '14px 18px', overflowY: 'auto', display: 'flex', flexDirection: 'column' };
  const footer:  React.CSSProperties = { padding: '12px 18px', borderTop: '1px solid #27272a' };
  const closeBtn:React.CSSProperties = { background: 'transparent', color: '#a1a1aa', border: 'none', fontSize: 18, cursor: 'pointer' };
  const clearBtn:React.CSSProperties = { background: 'transparent', color: '#a1a1aa', border: '1px solid #3f3f46', borderRadius: 4, padding: '4px 10px', fontSize: 12, cursor: 'pointer', marginRight: 8 };
  const errBox:  React.CSSProperties = { background: '#3b1d1d', border: '1px solid #7f1d1d', color: '#fecaca', padding: '8px 12px', borderRadius: 6, marginBottom: 10, fontSize: 13 };

  const handleSend = async (text: string) => {
    setBusy(true); setError(null);
    try {
      const canvas = summarizeCanvas(query.getSerializedNodes());
      const result = await send(text, canvas, target ? {
        node_id: target.nodeId,
        display_name: target.displayName,
        tree_json: target.treeJson,
      } : undefined);
      if (!result.ok) { setError(result.message || 'Failed'); return; }
      if (result.response.type === 'replace' && result.response.scope === 'site') {
        setPendingReplace(result.response);
        return;
      }
      const applied = await apply(result.response, target?.nodeId);
      if (!applied.ok) setError(applied.message || 'Apply failed');
    } catch (e: any) { setError(String(e?.message ?? e)); }
    finally { setBusy(false); }
  };

  const confirmReplace = async () => {
    if (!pendingReplace) return;
    const r = await apply(pendingReplace);
    setPendingReplace(null);
    if (!r.ok) setError(r.message || 'Apply failed');
  };

  const cancelClearChat = () => {
    if (clearChatTimeoutRef.current) clearTimeout(clearChatTimeoutRef.current);
    setConfirmClearChat(false);
  };

  const handleClearChatClick = async () => {
    if (!confirmClearChat) {
      setConfirmClearChat(true);
      if (clearChatTimeoutRef.current) clearTimeout(clearChatTimeoutRef.current);
      clearChatTimeoutRef.current = setTimeout(() => setConfirmClearChat(false), 4000);
      return;
    }
    cancelClearChat();
    const r = await clearHistory();
    if (!r.ok) setError(r.error || 'Failed to clear history');
  };

  return (
    <Modal
      open
      onClose={onClose}
      closeOnEscape={false}
      closeOnBackdropClick={false}
      backdropStyle={{ backgroundColor: 'rgba(0,0,0,0.8)' }}
      backdropProps={{ role: 'dialog', 'aria-modal': true }}
    >
      <div style={panel}>
        <div style={header}>
          <div style={{ fontWeight: 600, color: '#fff' }}>
            <i className="fa fa-magic" aria-hidden style={{ marginRight: 6 }} />
            Sitesmith
          </div>
          {summary && summary.enabled && (
            <div style={{ fontSize: 12, color: '#a1a1aa', marginLeft: 16 }}>
              {summary.monthly_used} / {summary.monthly_cap} this month
              {summary.bonus_credits > 0 && ` • +${summary.bonus_credits} bonus`}
            </div>
          )}
          <div style={{ flex: 1 }} />
          {messages.length > 0 && (
            confirmClearChat ? (
              <>
                <button
                  onClick={handleClearChatClick}
                  style={{ ...clearBtn, background: '#b91c1c', color: '#fff', borderColor: '#b91c1c' }}
                  title="Click again to permanently clear chat history"
                  autoFocus
                >
                  Confirm clear?
                </button>
                <button onClick={cancelClearChat} style={clearBtn} title="Cancel">
                  Cancel
                </button>
              </>
            ) : (
              <button
                onClick={handleClearChatClick}
                style={clearBtn}
                title="Clear all Sitesmith chat history for this site (canvas is unaffected)"
              >
                Clear chat
              </button>
            )
          )}
          <button onClick={onClose} aria-label="Close" style={closeBtn}><i className="fa fa-times" aria-hidden /></button>
        </div>
        <div style={body}>
          <UpgradeBanner summary={summary} />
          {target && (
            <div style={{
              background: 'rgba(59,130,246,0.12)', border: '1px solid rgba(59,130,246,0.4)',
              borderRadius: 6, padding: '8px 12px', marginBottom: 10, fontSize: 13, color: '#bfdbfe',
              display: 'flex', alignItems: 'center', gap: 8,
            }}>
              <i className="fa fa-magic" style={{ color: '#60a5fa' }} />
              <span>Editing <strong style={{ color: '#fff' }}>{target.displayName}</strong> — describe the change you want and Sitesmith will modify just this block.</span>
            </div>
          )}
          {error && <div role="alert" style={errBox}>{error}</div>}
          {loading
            ? <div style={{ color: '#71717a', textAlign: 'center', padding: 30 }}>Loading…</div>
            : <MessageList messages={messages} />}
        </div>
        <div style={footer}>
          {busy ? (
            <WorkingIndicator />
          ) : (
            <ChatInput
              disabled={!canChat}
              placeholder={!canChat ? 'Upgrade your plan to use Sitesmith' : 'Describe what you want…'}
              onSend={handleSend}
            />
          )}
        </div>
        <ScopeConfirmDialog
          open={!!pendingReplace}
          pendingMessage={pendingReplace && 'message' in pendingReplace ? (pendingReplace as any).message : undefined}
          onConfirm={confirmReplace}
          onCancel={() => setPendingReplace(null)}
        />
      </div>
    </Modal>
  );
};
