import React, { useState, useCallback, useRef, useEffect } from 'react';
import Editor, { type OnMount, type BeforeMount } from '@monaco-editor/react';
import { Button, Tooltip } from 'antd';
import {
  CloseOutlined,
  CopyOutlined,
  CheckOutlined,
  CodeOutlined,
} from '@ant-design/icons';
import type { PropDoc, ComponentVariant } from './types';

type IStandaloneCodeEditor = Parameters<OnMount>[0];

// ─── CopyButton ──────────────────────────────────────────────────────────────

const CopyButton: React.FC<{ text: string }> = ({ text }) => {
  const [copied, setCopied] = useState(false);
  return (
    <Tooltip title={copied ? '已复制' : '复制代码'}>
      <Button
        size="small"
        type="text"
        icon={
          copied ? (
            <CheckOutlined style={{ color: '#52c41a' }} />
          ) : (
            <CopyOutlined />
          )
        }
        onClick={() => {
          navigator.clipboard.writeText(text);
          setCopied(true);
          setTimeout(() => setCopied(false), 1500);
        }}
        style={{ fontSize: 12, color: 'rgba(0,0,0,0.45)' }}
      />
    </Tooltip>
  );
};

// ─── CodeFloatWindow ─────────────────────────────────────────────────────────

interface CodeFloatWindowProps {
  componentType: string;
  imports: string;
  code: string;
  props: PropDoc[];
  variants: ComponentVariant[];
  onChange: (code: string) => void;
  onClose: () => void;
}

const MIN_W = 360;
const MIN_H = 280;

type ResizeEdge = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';

const EDGE_CURSORS: Record<ResizeEdge, string> = {
  n: 'n-resize',
  s: 's-resize',
  e: 'e-resize',
  w: 'w-resize',
  ne: 'ne-resize',
  nw: 'nw-resize',
  se: 'se-resize',
  sw: 'sw-resize',
};

const CodeFloatWindow: React.FC<CodeFloatWindowProps> = ({
  componentType,
  imports,
  code,
  onChange,
  onClose,
}) => {
  const [pos, setPos] = useState({ x: 200, y: 80 });
  const [size, setSize] = useState({ w: 560, h: 480 });
  const dragging = useRef(false);
  const dragStart = useRef({ x: 0, y: 0, px: 0, py: 0 });
  const editorRef = useRef<IStandaloneCodeEditor | null>(null);

  // 拖动标题栏
  const handleTitleMouseDown = useCallback(
    (e: React.MouseEvent) => {
      e.preventDefault();
      dragging.current = true;
      dragStart.current = { x: e.clientX, y: e.clientY, px: pos.x, py: pos.y };

      const onMove = (ev: MouseEvent) => {
        if (!dragging.current) return;
        setPos({
          x: dragStart.current.px + (ev.clientX - dragStart.current.x),
          y: dragStart.current.py + (ev.clientY - dragStart.current.y),
        });
      };
      const onUp = () => {
        dragging.current = false;
        window.removeEventListener('mousemove', onMove);
        window.removeEventListener('mouseup', onUp);
      };
      window.addEventListener('mousemove', onMove);
      window.addEventListener('mouseup', onUp);
    },
    [pos],
  );

  // 拖拽边缘 resize
  const handleEdgeMouseDown = useCallback(
    (e: React.MouseEvent, edge: ResizeEdge) => {
      e.preventDefault();
      e.stopPropagation();
      const startX = e.clientX;
      const startY = e.clientY;
      const startW = size.w;
      const startH = size.h;
      const startPx = pos.x;
      const startPy = pos.y;

      const onMove = (ev: MouseEvent) => {
        const dx = ev.clientX - startX;
        const dy = ev.clientY - startY;

        setSize((prev) => {
          let w = prev.w;
          let h = prev.h;
          if (edge.includes('e')) w = Math.max(MIN_W, startW + dx);
          if (edge.includes('w')) w = Math.max(MIN_W, startW - dx);
          if (edge.includes('s')) h = Math.max(MIN_H, startH + dy);
          if (edge.includes('n')) h = Math.max(MIN_H, startH - dy);
          return { w, h };
        });

        setPos((prev) => {
          let x = prev.x;
          let y = prev.y;
          if (edge.includes('w')) x = startPx + Math.min(dx, startW - MIN_W);
          if (edge.includes('n')) y = startPy + Math.min(dy, startH - MIN_H);
          return { x, y };
        });
      };

      const onUp = () => {
        window.removeEventListener('mousemove', onMove);
        window.removeEventListener('mouseup', onUp);
      };
      window.addEventListener('mousemove', onMove);
      window.addEventListener('mouseup', onUp);
    },
    [size, pos],
  );

  // 同步外部 code 变化到 editor
  useEffect(() => {
    const editor = editorRef.current;
    if (!editor) return;
    const model = editor.getModel();
    if (model && model.getValue() !== code) {
      editor.executeEdits('external', [
        {
          range: model.getFullModelRange(),
          text: code,
          forceMoveMarkers: true,
        },
      ]);
    }
  }, [code]);

  // 配置 TypeScript/JSX 支持以获得完整语法高亮
  const handleBeforeMount: BeforeMount = useCallback((monaco) => {
    monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
      jsx: monaco.languages.typescript.JsxEmit.React,
      jsxFactory: 'React.createElement',
      reactNamespace: 'React',
      allowNonTsExtensions: true,
      allowJs: true,
      target: monaco.languages.typescript.ScriptTarget.Latest,
      module: monaco.languages.typescript.ModuleKind.ESNext,
      moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
      esModuleInterop: true,
    });
    // 关闭诊断（避免红色波浪线）
    monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
      noSemanticValidation: true,
      noSyntaxValidation: false,
    });
  }, []);

  const handleMount: OnMount = useCallback((editor) => {
    editorRef.current = editor;
  }, []);

  const HANDLE = 6;

  return (
    <div
      style={{
        position: 'fixed',
        left: pos.x,
        top: pos.y,
        width: size.w,
        height: size.h,
        background: '#fff',
        border: '1px solid #d9d9d9',
        borderRadius: 8,
        boxShadow:
          '0 6px 16px 0 rgba(0,0,0,0.08), 0 3px 6px -4px rgba(0,0,0,0.12), 0 9px 28px 8px rgba(0,0,0,0.05)',
        display: 'flex',
        flexDirection: 'column',
        zIndex: 1000,
        overflow: 'hidden',
      }}
    >
      {/* ── Resize handles (8 directions) ── */}
      {(['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'] as ResizeEdge[]).map(
        (edge) => {
          const isN = edge.includes('n');
          const isS = edge.includes('s');
          const isE = edge.includes('e');
          const isW = edge.includes('w');
          const isCorner = edge.length === 2;
          const cornerSize = HANDLE * 3;
          return (
            <div
              key={edge}
              onMouseDown={(e) => handleEdgeMouseDown(e, edge)}
              style={{
                position: 'absolute',
                cursor: EDGE_CURSORS[edge],
                zIndex: 10,
                top: isCorner
                  ? isN
                    ? 0
                    : undefined
                  : isN
                    ? 0
                    : isS
                      ? undefined
                      : HANDLE,
                bottom: isCorner
                  ? isS
                    ? 0
                    : undefined
                  : isS
                    ? 0
                    : isN
                      ? undefined
                      : HANDLE,
                left: isCorner
                  ? isW
                    ? 0
                    : undefined
                  : isW
                    ? 0
                    : isE
                      ? undefined
                      : HANDLE,
                right: isCorner
                  ? isE
                    ? 0
                    : undefined
                  : isE
                    ? 0
                    : isW
                      ? undefined
                      : HANDLE,
                width: isCorner ? cornerSize : isE || isW ? HANDLE : undefined,
                height: isCorner ? cornerSize : isN || isS ? HANDLE : undefined,
              }}
            />
          );
        },
      )}

      {/* 标题栏 */}
      <div
        onMouseDown={handleTitleMouseDown}
        style={{
          height: 40,
          padding: '0 16px',
          background: '#fafafa',
          borderBottom: '1px solid #f0f0f0',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          cursor: 'move',
          flexShrink: 0,
          userSelect: 'none',
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <CodeOutlined style={{ fontSize: 14, color: '#1677ff' }} />
          <span
            style={{ fontSize: 13, fontWeight: 600, color: 'rgba(0,0,0,0.88)' }}
          >
            {componentType}
          </span>
        </div>
        <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
          <CopyButton text={`${imports}\n\n${code}`} />
          <Button
            size="small"
            type="text"
            icon={<CloseOutlined />}
            onClick={onClose}
            style={{ color: 'rgba(0,0,0,0.45)' }}
          />
        </div>
      </div>

      {/* Imports（只读提示条） */}
      <div
        style={{
          background: '#f6f8fa',
          borderBottom: '1px solid #f0f0f0',
          padding: '6px 16px',
          flexShrink: 0,
        }}
      >
        <pre
          style={{
            margin: 0,
            fontSize: 13,
            color: '#1677ff',
            fontFamily:
              "'JetBrains Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
            lineHeight: 1.5,
            whiteSpace: 'pre-wrap',
            opacity: 0.85,
          }}
        >
          {imports}
        </pre>
      </div>

      {/* Monaco 编辑器 */}
      <div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>
        <Editor
          defaultLanguage="typescript"
          defaultPath="component.tsx"
          value={code}
          onChange={(val) => onChange(val ?? '')}
          beforeMount={handleBeforeMount}
          onMount={handleMount}
          theme="vs"
          options={{
            minimap: { enabled: false },
            fontSize: 14,
            fontFamily:
              "'JetBrains Mono', 'Fira Code', Menlo, Monaco, 'Courier New', monospace",
            fontLigatures: true,
            lineNumbers: 'on',
            lineNumbersMinChars: 3,
            scrollBeyondLastLine: false,
            automaticLayout: true,
            tabSize: 2,
            renderLineHighlight: 'line',
            padding: { top: 8, bottom: 8 },
            wordWrap: 'on',
            folding: true,
            bracketPairColorization: { enabled: true },
            guides: { bracketPairs: true },
          }}
        />
      </div>
    </div>
  );
};

export default CodeFloatWindow;
