'use client';

import { useState, useRef, useCallback, useEffect } from 'react';
import { Plus, Trash2, X, ChevronDown, ChevronUp } from 'lucide-react';
import { useCalculateStore } from '@/lib/calculate/store';
import { evaluateExpression } from '@/lib/calculate/math-engine';
import { cn } from '@/lib/utils';

const QUICK_KEYS = [
  // Constants
  { label: 'π', insert: 'pi', group: 'const' },
  { label: 'e', insert: 'e', group: 'const' },
  { label: 'φ', insert: '(1+sqrt(5))/2', group: 'const' },
  { label: '∞', insert: 'Infinity', group: 'const' },
  { label: 'i', insert: 'i', group: 'const' },
  // Ops
  { label: '^', insert: '^', group: 'op' },
  { label: '(', insert: '(', group: 'op' },
  { label: ')', insert: ')', group: 'op' },
  { label: '%', insert: ' % ', group: 'op' },
  { label: 'mod', insert: ' mod ', group: 'op' },
  // Functions
  { label: '√', insert: 'sqrt(', group: 'fn' },
  { label: '∛', insert: 'cbrt(', group: 'fn' },
  { label: '|x|', insert: 'abs(', group: 'fn' },
  { label: 'n!', insert: '!', group: 'fn' },
  { label: 'sin', insert: 'sin(', group: 'trig' },
  { label: 'cos', insert: 'cos(', group: 'trig' },
  { label: 'tan', insert: 'tan(', group: 'trig' },
  { label: 'asin', insert: 'asin(', group: 'trig' },
  { label: 'acos', insert: 'acos(', group: 'trig' },
  { label: 'atan', insert: 'atan(', group: 'trig' },
  { label: 'sinh', insert: 'sinh(', group: 'trig' },
  { label: 'cosh', insert: 'cosh(', group: 'trig' },
  { label: 'log', insert: 'log10(', group: 'log' },
  { label: 'ln', insert: 'log(', group: 'log' },
  { label: 'log₂', insert: 'log2(', group: 'log' },
  { label: 'exp', insert: 'exp(', group: 'log' },
  { label: 'floor', insert: 'floor(', group: 'round' },
  { label: 'ceil', insert: 'ceil(', group: 'round' },
  { label: 'round', insert: 'round(', group: 'round' },
  { label: 'gcd', insert: 'gcd(', group: 'misc' },
  { label: 'lcm', insert: 'lcm(', group: 'misc' },
  { label: 'nCr', insert: 'combinations(', group: 'misc' },
  { label: 'nPr', insert: 'permutations(', group: 'misc' },
] as const;

export function ExpressionPanel() {
  const {
    expression, setExpression,
    history, addToHistory, clearHistory,
    variables, setVariable, removeVariable,
  } = useCalculateStore();

  const [liveResult, setLiveResult] = useState<{ result: string; error: boolean } | null>(null);
  const [newVarName, setNewVarName] = useState('');
  const [newVarValue, setNewVarValue] = useState('');
  const [showAddVar, setShowAddVar] = useState(false);
  const [showAllKeys, setShowAllKeys] = useState(false);
  const textareaRef = useRef<HTMLTextAreaElement>(null);

  // Real-time evaluation
  useEffect(() => {
    if (!expression.trim()) { setLiveResult(null); return; }
    const r = evaluateExpression(expression, variables);
    setLiveResult(r.result ? { result: r.result, error: r.error } : null);
  }, [expression, variables]);

  const handleSubmit = useCallback(() => {
    if (!expression.trim()) return;
    const r = evaluateExpression(expression, variables);
    if (!r.result) return;
    addToHistory({ expression: expression.trim(), result: r.result, error: r.error });
    if (!r.error) {
      if (r.assignedName && r.assignedValue) {
        setVariable(r.assignedName, r.assignedValue);
      }
      setExpression('');
    }
  }, [expression, variables, addToHistory, setExpression, setVariable]);

  const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSubmit();
    }
  }, [handleSubmit]);

  const insertAtCursor = useCallback((text: string) => {
    const ta = textareaRef.current;
    if (!ta) { setExpression(expression + text); return; }
    const start = ta.selectionStart;
    const end = ta.selectionEnd;
    const next = expression.slice(0, start) + text + expression.slice(end);
    setExpression(next);
    requestAnimationFrame(() => {
      ta.focus();
      const pos = start + text.length;
      ta.selectionStart = ta.selectionEnd = pos;
    });
  }, [expression, setExpression]);

  const addVar = useCallback(() => {
    if (!newVarName.trim() || !newVarValue.trim()) return;
    setVariable(newVarName.trim(), newVarValue.trim());
    setNewVarName(''); setNewVarValue(''); setShowAddVar(false);
  }, [newVarName, newVarValue, setVariable]);

  const visibleKeys = showAllKeys ? QUICK_KEYS : QUICK_KEYS.slice(0, 16);

  return (
    <div className="flex flex-col gap-3 h-full overflow-hidden">

      {/* ── Expression input ──────────────────────────────────── */}
      <div className="glass rounded-xl p-4 shrink-0">
        <div className="flex items-center justify-between mb-2">
          <span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
            Expression
          </span>
          <span className="text-[10px] text-muted-foreground/50">
            Enter to evaluate · Shift+Enter for newline
          </span>
        </div>

        <textarea
          ref={textareaRef}
          value={expression}
          onChange={(e) => setExpression(e.target.value)}
          onKeyDown={handleKeyDown}
          placeholder="e.g.  sin(pi/4) * sqrt(2)"
          rows={3}
          className={cn(
            'w-full bg-transparent resize-none font-mono text-sm outline-none',
            'text-foreground placeholder:text-muted-foreground/35',
            'border border-border/40 rounded-lg px-3 py-2.5',
            'focus:border-primary/50 transition-colors'
          )}
          spellCheck={false}
          autoComplete="off"
        />

        {/* Result display */}
        <div className="mt-3 flex items-baseline gap-2 min-h-[2rem]">
          {liveResult && (
            <>
              <span className="font-mono text-muted-foreground shrink-0">=</span>
              <span
                className={cn(
                  'font-mono font-semibold break-all',
                  liveResult.error
                    ? 'text-sm text-destructive/90'
                    : 'text-2xl bg-gradient-to-r from-primary to-pink-400 bg-clip-text text-transparent'
                )}
              >
                {liveResult.result}
              </span>
            </>
          )}
        </div>

        <button
          onClick={handleSubmit}
          disabled={!expression.trim()}
          className={cn(
            'mt-2 w-full py-2 rounded-lg text-xs font-medium transition-all',
            'bg-primary/90 text-primary-foreground hover:bg-primary',
            'disabled:opacity-30 disabled:cursor-not-allowed'
          )}
        >
          Evaluate
        </button>
      </div>

      {/* ── Quick insert keys ─────────────────────────────────── */}
      <div className="glass rounded-xl p-3 shrink-0">
        <div className="flex items-center justify-between mb-2">
          <span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
            Insert
          </span>
          <button
            onClick={() => setShowAllKeys((v) => !v)}
            className="flex items-center gap-0.5 text-[10px] text-muted-foreground/60 hover:text-muted-foreground transition-colors"
          >
            {showAllKeys ? (
              <><ChevronUp className="w-3 h-3" /> less</>
            ) : (
              <><ChevronDown className="w-3 h-3" /> more</>
            )}
          </button>
        </div>
        <div className="flex flex-wrap gap-1">
          {visibleKeys.map((k) => (
            <button
              key={k.label}
              onClick={() => insertAtCursor(k.insert)}
              className={cn(
                'px-2 py-1 text-xs font-mono rounded-md transition-all',
                'glass border border-transparent',
                'hover:border-primary/30 hover:bg-primary/10 hover:text-primary',
                'text-foreground/80'
              )}
            >
              {k.label}
            </button>
          ))}
        </div>
      </div>

      {/* ── Variables ─────────────────────────────────────────── */}
      <div className="glass rounded-xl p-3 shrink-0">
        <div className="flex items-center justify-between mb-2">
          <span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
            Variables
          </span>
          <button
            onClick={() => setShowAddVar((v) => !v)}
            className="text-muted-foreground hover:text-primary transition-colors"
            title="Add variable"
          >
            <Plus className="w-3.5 h-3.5" />
          </button>
        </div>

        {Object.keys(variables).length === 0 && !showAddVar && (
          <p className="text-xs text-muted-foreground/40 italic">
            Define variables like <span className="font-mono not-italic">x = 5</span> by evaluating assignments
          </p>
        )}

        <div className="space-y-1">
          {Object.entries(variables).map(([name, val]) => (
            <div key={name} className="flex items-center gap-2 group">
              <span
                className="font-mono text-sm text-primary cursor-pointer hover:underline"
                onClick={() => insertAtCursor(name)}
                title="Insert into expression"
              >
                {name}
              </span>
              <span className="text-muted-foreground/50 text-xs">=</span>
              <span className="font-mono text-sm text-foreground/80 flex-1 truncate">{val}</span>
              <button
                onClick={() => removeVariable(name)}
                className="opacity-0 group-hover:opacity-100 text-muted-foreground/50 hover:text-destructive transition-all"
              >
                <X className="w-3 h-3" />
              </button>
            </div>
          ))}
        </div>

        {showAddVar && (
          <div className="flex items-center gap-1.5 mt-2">
            <input
              value={newVarName}
              onChange={(e) => setNewVarName(e.target.value)}
              placeholder="name"
              className="w-16 bg-transparent border border-border/40 rounded px-2 py-1 text-xs font-mono outline-none focus:border-primary/50 transition-colors"
            />
            <span className="text-muted-foreground/50 text-xs">=</span>
            <input
              value={newVarValue}
              onChange={(e) => setNewVarValue(e.target.value)}
              placeholder="value"
              onKeyDown={(e) => e.key === 'Enter' && addVar()}
              className="flex-1 bg-transparent border border-border/40 rounded px-2 py-1 text-xs font-mono outline-none focus:border-primary/50 transition-colors"
            />
            <button
              onClick={addVar}
              className="text-primary hover:text-primary/70 transition-colors"
            >
              <Plus className="w-3.5 h-3.5" />
            </button>
            <button
              onClick={() => setShowAddVar(false)}
              className="text-muted-foreground/50 hover:text-muted-foreground transition-colors"
            >
              <X className="w-3.5 h-3.5" />
            </button>
          </div>
        )}
      </div>

      {/* ── History ───────────────────────────────────────────── */}
      <div className="glass rounded-xl p-3 flex-1 min-h-0 flex flex-col overflow-hidden">
        <div className="flex items-center justify-between mb-2 shrink-0">
          <span className="text-[10px] font-semibold text-muted-foreground uppercase tracking-widest">
            History
          </span>
          {history.length > 0 && (
            <button
              onClick={clearHistory}
              className="text-muted-foreground/50 hover:text-destructive transition-colors"
              title="Clear history"
            >
              <Trash2 className="w-3.5 h-3.5" />
            </button>
          )}
        </div>

        {history.length === 0 ? (
          <p className="text-xs text-muted-foreground/40 italic">No calculations yet</p>
        ) : (
          <div className="overflow-y-auto flex-1 space-y-0.5 scrollbar-thin scrollbar-thumb-primary/20 scrollbar-track-transparent">
            {history.map((entry) => (
              <button
                key={entry.id}
                onClick={() => setExpression(entry.expression)}
                className="w-full text-left px-2 py-2 rounded-lg hover:bg-primary/8 group transition-colors"
              >
                <div className="font-mono text-[11px] text-muted-foreground/70 truncate group-hover:text-muted-foreground transition-colors">
                  {entry.expression}
                </div>
                <div className={cn(
                  'font-mono text-sm font-medium mt-0.5',
                  entry.error ? 'text-destructive/80' : 'text-foreground/90'
                )}>
                  = {entry.result}
                </div>
              </button>
            ))}
          </div>
        )}
      </div>

    </div>
  );
}
