import React, { useEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { safeSendMessage, safeStorageGet, safeStorageSet } from '@lib/messaging';

import { WRITING_STYLES, PROMPT_PATTERNS, PROMPT_PERSONAS, PROMPT_FORMATS, resolvePromptPersona, resolvePromptPattern } from '@lib/actions';
import type { PromptParams } from '@lib/types';

// ─── Types ───────────────────────────────────────────────────────────────────

type Action = 'fix' | 'rephrase' | 'shorten' | 'expand' | 'prompt';

// ─── Styles ──────────────────────────────────────────────────────────────────

const S = {
  root: {
    fontFamily: 'system-ui, -apple-system, sans-serif',
    background: '#1e1e2e',
    color: '#cdd6f4',
    padding: '0',
    minWidth: '420px',
    maxHeight: '600px',
    overflowY: 'auto' as const,
  },
  header: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: '12px 16px',
    borderBottom: '1px solid rgba(205,214,244,0.1)',
  },
  headerLeft: {
    display: 'flex',
    alignItems: 'center',
    gap: '6px',
    fontSize: '16px',
    fontWeight: 700,
  },
  settingsBtn: {
    background: 'none',
    border: '1px solid rgba(205,214,244,0.2)',
    borderRadius: '6px',
    color: '#a6adc8',
    cursor: 'pointer',
    fontSize: '12px',
    padding: '4px 10px',
  },
  section: {
    padding: '14px 16px',
  },
  tabBar: {
    display: 'flex',
    borderBottom: '1px solid rgba(205,214,244,0.1)',
  },
  tab: {
    flex: 1,
    background: 'none',
    border: 'none',
    borderBottom: '2px solid transparent',
    color: '#6c7086',
    cursor: 'pointer',
    fontSize: '13px',
    fontWeight: 600,
    padding: '10px 0',
  },
  tabActive: {
    color: '#89b4fa',
    borderBottom: '2px solid #89b4fa',
  },
  divider: {
    borderTop: '1px solid rgba(205,214,244,0.1)',
  },
  textarea: {
    width: '100%',
    minHeight: '100px',
    background: 'rgba(49,50,68,0.95)',
    border: '1px solid rgba(205,214,244,0.15)',
    borderRadius: '8px',
    color: '#cdd6f4',
    fontSize: '13px',
    lineHeight: '1.5',
    padding: '10px 12px',
    resize: 'vertical' as const,
    outline: 'none',
    boxSizing: 'border-box' as const,
    fontFamily: 'inherit',
  },
  styleRow: {
    display: 'flex',
    alignItems: 'center',
    gap: '8px',
    marginTop: '10px',
    marginBottom: '2px',
  },
  styleLabel: {
    fontSize: '12px',
    color: '#a6adc8',
    flexShrink: 0,
  },
  styleSelect: {
    background: 'rgba(49,50,68,0.95)',
    border: '1px solid rgba(205,214,244,0.2)',
    borderRadius: '6px',
    color: '#cdd6f4',
    fontSize: '12px',
    padding: '4px 8px',
    cursor: 'pointer',
    flex: 1,
    outline: 'none',
  },
  actionsRow: {
    display: 'flex',
    flexWrap: 'wrap' as const,
    gap: '8px',
    marginTop: '10px',
  },
  actionBtn: {
    background: 'linear-gradient(135deg, #cba6f7, #89b4fa)',
    border: 'none',
    borderRadius: '6px',
    color: '#1e1e2e',
    cursor: 'pointer',
    fontSize: '12px',
    fontWeight: 600,
    padding: '6px 12px',
  },
  actionBtnDisabled: {
    background: 'rgba(203,166,247,0.3)',
    border: 'none',
    borderRadius: '6px',
    color: '#a6adc8',
    cursor: 'not-allowed',
    fontSize: '12px',
    fontWeight: 600,
    padding: '6px 12px',
  },
  processingBadge: {
    fontSize: '12px',
    color: '#a6adc8',
    marginTop: '8px',
  },
  resultSection: {
    padding: '0 16px 14px',
  },
  resultLabel: {
    fontSize: '12px',
    color: '#a6adc8',
    marginBottom: '6px',
    fontWeight: 600,
  },
  resultBox: {
    background: 'rgba(49,50,68,0.8)',
    border: '1px solid rgba(205,214,244,0.1)',
    borderRadius: '8px',
    color: '#cdd6f4',
    fontSize: '13px',
    lineHeight: '1.5',
    padding: '10px 12px',
    whiteSpace: 'pre-wrap' as const,
    wordBreak: 'break-word' as const,
  },
  copyBtn: {
    marginTop: '8px',
    background: 'rgba(137,180,250,0.15)',
    border: '1px solid rgba(137,180,250,0.3)',
    borderRadius: '6px',
    color: '#89b4fa',
    cursor: 'pointer',
    fontSize: '12px',
    fontWeight: 600,
    padding: '6px 14px',
  },
  warningBox: {
    background: 'rgba(243,139,168,0.1)',
    border: '1px solid rgba(243,139,168,0.3)',
    borderRadius: '8px',
    color: '#f38ba8',
    fontSize: '12px',
    padding: '10px 12px',
    marginBottom: '12px',
  },
  errorBox: {
    background: 'rgba(243,139,168,0.1)',
    border: '1px solid rgba(243,139,168,0.3)',
    borderRadius: '8px',
    color: '#f38ba8',
    fontSize: '12px',
    padding: '10px 12px',
    marginTop: '8px',
  },
};

// ─── Component ────────────────────────────────────────────────────────────────

function Popup() {
  const [configured, setConfigured] = useState(false);
  const [provider, setProvider] = useState('');
  const [model, setModel] = useState('');
  const [inputText, setInputText] = useState('');
  const [result, setResult] = useState('');
  const [error, setError] = useState('');
  const [processing, setProcessing] = useState(false);
  const [copied, setCopied] = useState(false);
  const [writingStyle, setWritingStyle] = useState('Default');
  // Prompt Builder parameters — persisted so they survive popup close/open.
  const [promptPattern, setPromptPattern] = useState('auto');
  const [promptPersona, setPromptPersona] = useState('Auto');
  const [customPersona, setCustomPersona] = useState('');
  const [promptFormat, setPromptFormat] = useState('Auto');
  // Model used for building the prompt ('' = the configured default model).
  const [promptModel, setPromptModel] = useState('');
  const [promptModels, setPromptModels] = useState<string[]>([]);
  const [modelsHint, setModelsHint] = useState('');
  const modelsRequested = useRef(false);
  const [tab, setTab] = useState<'writing' | 'prompt'>('writing');
  const sessionRestored = useRef(false);

  // Load config + restore session input + load writing style
  useEffect(() => {
    safeStorageGet(
      ['provider', 'apiKey', 'apiKeyEnc', 'model', 'writingStyle', 'promptPattern', 'promptStyle', 'promptPersona', 'customPersona', 'promptFormat', 'promptModel', 'popupTab'],
      (result) => {
        if (result.apiKey || result.apiKeyEnc) {
          setConfigured(true);
          setProvider(result.provider || 'openai');
          setModel(result.model || '');
        }
        if (result.writingStyle) {
          setWritingStyle(result.writingStyle);
        }
        if (result.promptPattern || result.promptStyle) {
          setPromptPattern(resolvePromptPattern(result.promptPattern, result.promptStyle));
        }
        if (result.promptPersona) setPromptPersona(result.promptPersona);
        if (result.customPersona) setCustomPersona(result.customPersona);
        if (result.promptFormat) setPromptFormat(result.promptFormat);
        if (result.promptModel) setPromptModel(result.promptModel);
        if (result.popupTab === 'prompt' || result.popupTab === 'writing') setTab(result.popupTab);
      },
    );

    if (!sessionRestored.current) {
      sessionRestored.current = true;
      safeStorageGet(['lexai_popup_input'], (res) => {
        if (res.lexai_popup_input) {
          setInputText(res.lexai_popup_input);
        }
      }, chrome.storage.session);
    }
  }, []);

  // Persist input to session storage on change
  const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    const val = e.target.value;
    setInputText(val);
    safeStorageSet({ lexai_popup_input: val }, undefined, chrome.storage.session);
  };

  // Save writing style on change
  const handleStyleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const val = e.target.value;
    setWritingStyle(val);
    safeStorageSet({ writingStyle: val });
  };

  const openSettings = () => {
    try {
      if (typeof chrome !== 'undefined' && chrome.runtime?.id) {
        chrome.runtime.openOptionsPage();
      }
    } catch (err) {
      console.warn('LexAI: Extension context invalidated', err);
    }
  };

  // Resolve the Prompt Builder selections into message params. 'Custom…'
  // uses the free-text persona (falls back to Auto when left empty).
  const resolvePromptParams = (): PromptParams => ({
    pattern: promptPattern,
    persona: resolvePromptPersona(promptPersona, customPersona),
    format: promptFormat,
  });

  const runAction = async (action: Action) => {
    const text = inputText.trim();
    if (!text || processing) return;

    setProcessing(true);
    setResult('');
    setError('');

    const response = await safeSendMessage({
      type: 'ANALYZE_TEXT',
      payload: {
        text,
        action,
        style: writingStyle,
        ...(action === 'prompt'
          ? {
              promptParams: resolvePromptParams(),
              ...(promptModel ? { model: promptModel } : {}),
            }
          : {}),
      },
    });

    setProcessing(false);

    if (!response) {
      setError('No response from extension. Try reloading.');
      return;
    }
    if (response.error) {
      setError(response.error);
      return;
    }
    if (response.result) {
      setResult(response.result);
    }
  };

  const copyResult = async () => {
    if (!result) return;
    try {
      await navigator.clipboard.writeText(result);
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    } catch {
      // fallback
    }
  };

  const actions: { label: string; id: Action }[] = [
    { label: 'Fix Grammar', id: 'fix' },
    { label: 'Rephrase', id: 'rephrase' },
    { label: 'Shorten', id: 'shorten' },
    { label: 'Expand', id: 'expand' },
  ];

  // Persist one Prompt Builder param alongside its state update.
  const setParam = (key: string, value: string, setter: (v: string) => void) => {
    setter(value);
    safeStorageSet({ [key]: value });
  };

  const switchTab = (t: 'writing' | 'prompt') => {
    setTab(t);
    safeStorageSet({ popupTab: t });
  };

  // Fetch the provider's model list the first time the Prompt Builder tab is
  // shown (background worker resolves the stored key). Failure is non-fatal —
  // the picker just stays on the default model.
  useEffect(() => {
    if (tab !== 'prompt' || !configured || modelsRequested.current) return;
    modelsRequested.current = true;
    (async () => {
      const res = await safeSendMessage({ type: 'LIST_MODELS', provider });
      if (res?.models && Array.isArray(res.models)) {
        setPromptModels(res.models);
      } else {
        setModelsHint(res?.error || 'Could not load the model list — using the default model.');
      }
    })();
  }, [tab, configured, provider]);

  return (
    <div style={S.root}>
      {/* Header */}
      <div style={S.header}>
        <div style={S.headerLeft}>
          <span>⚡</span>
          <span>LexAI</span>
        </div>
        <button style={S.settingsBtn} onClick={openSettings}>
          ⚙ Settings
        </button>
      </div>

      {/* Not configured warning */}
      {!configured && (
        <div style={S.section}>
          <div style={S.warningBox}>
            <strong>⚠ Setup Required</strong>
            <br />
            Add your API key in Settings to use LexAI.
          </div>
          <button
            onClick={openSettings}
            style={{
              ...S.actionBtn,
              width: '100%',
              fontSize: '13px',
              padding: '8px',
            }}
          >
            ⚙ Open Settings
          </button>
        </div>
      )}

      {/* Main input area — only when configured */}
      {configured && (
        <>
          {/* Tabs: quick writing actions vs. the Prompt Builder */}
          <div style={S.tabBar}>
            <button
              style={tab === 'writing' ? { ...S.tab, ...S.tabActive } : S.tab}
              onClick={() => switchTab('writing')}
            >
              ✍ Writing
            </button>
            <button
              style={tab === 'prompt' ? { ...S.tab, ...S.tabActive } : S.tab}
              onClick={() => switchTab('prompt')}
            >
              🪄 Prompt Builder
            </button>
          </div>

          <div style={S.section}>
            {/* Provider badge */}
            <div style={{ fontSize: '11px', color: '#a6adc8', marginBottom: '8px' }}>
              ✓ {provider}
              {/* Model shown only on the Writing tab — the Prompt Builder has its own Model field */}
              {tab === 'writing' && model ? ` / ${model}` : ''}
            </div>

            {/* Textarea */}
            <textarea
              style={S.textarea}
              placeholder="Paste your text here..."
              value={inputText}
              onChange={handleInputChange}
              disabled={processing}
              rows={4}
            />

            {/* Writing tab: style + quick actions */}
            {tab === 'writing' && (
              <>
                <div style={S.styleRow}>
                  <span style={S.styleLabel}>Style:</span>
                  <select
                    style={S.styleSelect}
                    value={writingStyle}
                    onChange={handleStyleChange}
                    disabled={processing}
                  >
                    {WRITING_STYLES.map(s => (
                      <option key={s} value={s}>{s}</option>
                    ))}
                  </select>
                </div>

                <div style={S.actionsRow}>
                  {actions.map(({ label, id }) => (
                    <button
                      key={id}
                      style={processing ? S.actionBtnDisabled : S.actionBtn}
                      disabled={processing || !inputText.trim()}
                      onClick={() => runAction(id)}
                    >
                      {label}
                    </button>
                  ))}
                </div>
              </>
            )}

            {/* Prompt Builder tab: dedicated parameters + model + Make Prompt */}
            {tab === 'prompt' && (
              <>
                <div style={{ fontSize: '11px', color: '#6c7086', margin: '8px 0 2px' }}>
                  Turns the text above into an engineered AI prompt. "Auto" lets it decide from your input.
                </div>

                <div style={{ ...S.styleRow, marginTop: '6px' }}>
                  <span style={{ ...S.styleLabel, width: '64px' }}>Pattern:</span>
                  <select
                    style={S.styleSelect}
                    value={promptPattern}
                    onChange={(e) => setParam('promptPattern', e.target.value, setPromptPattern)}
                    disabled={processing}
                  >
                    {PROMPT_PATTERNS.filter((p) => p.id === 'auto').map((p) => (
                      <option key={p.id} value={p.id} title={p.hint}>{p.label}</option>
                    ))}
                    {(['Direct', 'Reasoning', 'Agentic'] as const).map((group) => (
                      <optgroup key={group} label={group}>
                        {PROMPT_PATTERNS.filter((p) => p.id !== 'auto' && p.group === group).map((p) => (
                          <option key={p.id} value={p.id} title={p.hint}>{p.label}</option>
                        ))}
                      </optgroup>
                    ))}
                  </select>
                </div>
                <div style={{ fontSize: '11px', color: '#6c7086', margin: '2px 0 0 72px' }}>
                  {PROMPT_PATTERNS.find((p) => p.id === promptPattern)?.hint}
                </div>

                <div style={{ ...S.styleRow, marginTop: '6px' }}>
                  <span style={{ ...S.styleLabel, width: '64px' }}>Persona:</span>
                  <select
                    style={S.styleSelect}
                    value={promptPersona}
                    onChange={(e) => setParam('promptPersona', e.target.value, setPromptPersona)}
                    disabled={processing}
                  >
                    {PROMPT_PERSONAS.map((p) => (
                      <option key={p} value={p}>{p}</option>
                    ))}
                  </select>
                </div>

                {promptPersona === 'Custom…' && (
                  <div style={{ ...S.styleRow, marginTop: '6px' }}>
                    <span style={{ ...S.styleLabel, width: '64px' }} />
                    <input
                      type="text"
                      style={{ ...S.styleSelect, cursor: 'text' }}
                      placeholder="e.g. senior UX researcher who writes usability reports"
                      value={customPersona}
                      onChange={(e) => setParam('customPersona', e.target.value, setCustomPersona)}
                      disabled={processing}
                    />
                  </div>
                )}

                <div style={{ ...S.styleRow, marginTop: '6px' }}>
                  <span style={{ ...S.styleLabel, width: '64px' }}>Format:</span>
                  <select
                    style={S.styleSelect}
                    value={promptFormat}
                    onChange={(e) => setParam('promptFormat', e.target.value, setPromptFormat)}
                    disabled={processing}
                  >
                    {PROMPT_FORMATS.map((f) => (
                      <option key={f} value={f}>{f}</option>
                    ))}
                  </select>
                </div>

                <div style={{ ...S.styleRow, marginTop: '6px' }}>
                  <span style={{ ...S.styleLabel, width: '64px' }}>Model:</span>
                  <select
                    style={S.styleSelect}
                    value={promptModel}
                    onChange={(e) => setParam('promptModel', e.target.value, setPromptModel)}
                    disabled={processing}
                  >
                    <option value="">Default</option>
                    {promptModels.map((m) => (
                      <option key={m} value={m}>{m}</option>
                    ))}
                  </select>
                </div>
                {modelsHint && (
                  <div style={{ fontSize: '11px', color: '#6c7086', marginTop: '4px' }}>
                    ⚠ {modelsHint}
                  </div>
                )}

                <div style={S.actionsRow}>
                  <button
                    style={{
                      ...(processing ? S.actionBtnDisabled : S.actionBtn),
                      ...(processing ? {} : { background: 'linear-gradient(135deg, #f9e2af, #fab387)' }),
                      width: '100%',
                      padding: '8px',
                      fontSize: '13px',
                    }}
                    disabled={processing || !inputText.trim()}
                    onClick={() => runAction('prompt')}
                  >
                    🪄 Make Prompt
                  </button>
                </div>
              </>
            )}

            {/* Processing state */}
            {processing && (
              <div style={S.processingBadge}>⏳ Processing...</div>
            )}

            {/* Error */}
            {error && <div style={S.errorBox}>⚠ {error}</div>}
          </div>

          {/* Result area */}
          {result && (
            <>
              <div style={S.divider} />
              <div style={S.resultSection}>
                <div style={S.resultLabel}>Result:</div>
                <div style={S.resultBox}>{result}</div>
                <button style={S.copyBtn} onClick={copyResult}>
                  {copied ? '✓ Copied!' : '⎘ Copy Result'}
                </button>
              </div>
            </>
          )}
        </>
      )}
    </div>
  );
}

createRoot(document.getElementById('app')!).render(<Popup />);
