'use client';

/**
 * Toolbar Component
 * 顶部工具栏组件
 */

import React, { useCallback, useMemo } from 'react';
import { useEditorStore } from '../../stores/useEditorStore';
import { cn } from '@/lib/utils';
import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';
import { wrapInList } from 'prosemirror-schema-list';
import { undo, redo } from 'prosemirror-history';
import {
  Bold,
  Italic,
  Underline as UnderlineIcon,
  Strikethrough,
  Code,
  Highlighter,
  Link2,
  Heading1,
  Heading2,
  Heading3,
  List,
  ListOrdered,
  Quote,
  Minus,
  Undo,
  Redo,
  type LucideIcon,
} from 'lucide-react';
import { useTranslation } from '@/hooks/useTranslation';

export interface ToolbarProps {
  className?: string;
}

interface ToolbarButtonConfig {
  name: string;
  icon: LucideIcon;
  title: string;
  type: 'mark' | 'node' | 'command';
  markName?: string;
  nodeName?: string;
  action?: () => void;
  isActive?: () => boolean;
}

export function Toolbar({ className }: ToolbarProps) {
  const { t } = useTranslation();
  const { view, openLinkEditor } = useEditorStore();

  // 检查标记是否激活
  const isMarkActive = useCallback(
    (markName: string) => {
      if (!view) return false;
      const { state } = view;
      const markType = state.schema.marks[markName];
      if (!markType) return false;

      const { from, to, empty } = state.selection;
      if (empty) {
        return !!markType.isInSet(state.storedMarks || state.selection.$from.marks());
      }
      return state.doc.rangeHasMark(from, to, markType);
    },
    [view]
  );

  // 检查块级节点是否激活
  const isNodeActive = useCallback(
    (nodeName: string, attrs?: Record<string, unknown>) => {
      if (!view) return false;
      const { state } = view;
      const nodeType = state.schema.nodes[nodeName];
      if (!nodeType) return false;

      const { $from } = state.selection;
      for (let d = $from.depth; d >= 0; d--) {
        const node = $from.node(d);
        if (node.type === nodeType) {
          if (!attrs) return true;
          return Object.entries(attrs).every(([key, value]) => node.attrs[key] === value);
        }
      }
      return false;
    },
    [view]
  );

  // 切换标记
  const toggleMarkAction = useCallback(
    (markName: string) => {
      if (!view) return;
      const { state, dispatch } = view;
      const markType = state.schema.marks[markName];
      if (!markType) return;
      toggleMark(markType)(state, dispatch);
      view.focus();
    },
    [view]
  );

  // 设置块级类型
  const setBlockTypeAction = useCallback(
    (nodeName: string, attrs?: Record<string, unknown>) => {
      if (!view) return;
      const { state, dispatch } = view;
      const nodeType = state.schema.nodes[nodeName];
      if (!nodeType) return;
      setBlockType(nodeType, attrs)(state, dispatch);
      view.focus();
    },
    [view]
  );

  // 包装为列表
  const wrapInListAction = useCallback(
    (listType: string) => {
      if (!view) return;
      const { state, dispatch } = view;
      const nodeType = state.schema.nodes[listType];
      if (!nodeType) return;
      wrapInList(nodeType)(state, dispatch);
      view.focus();
    },
    [view]
  );

  // 包装为引用
  const wrapInBlockquote = useCallback(() => {
    if (!view) return;
    const { state, dispatch } = view;
    const blockquoteType = state.schema.nodes.blockquote;
    if (!blockquoteType) return;
    wrapIn(blockquoteType)(state, dispatch);
    view.focus();
  }, [view]);

  // 插入分割线
  const insertHorizontalRule = useCallback(() => {
    if (!view) return;
    const { state, dispatch } = view;
    const hrType = state.schema.nodes.horizontalRule;
    if (!hrType) return;
    const tr = state.tr.replaceSelectionWith(hrType.create());
    dispatch(tr);
    view.focus();
  }, [view]);

  // 打开链接编辑器
  const handleLinkClick = useCallback(() => {
    if (!view) return;
    const { state } = view;
    const { from, to } = state.selection;
    const coords = view.coordsAtPos(from);
    const text = state.doc.textBetween(from, to);

    const markType = state.schema.marks.link;
    let existingHref = '';
    if (markType) {
      state.doc.nodesBetween(from, to, (node) => {
        const linkMark = markType.isInSet(node.marks);
        if (linkMark) {
          existingHref = linkMark.attrs.href;
        }
      });
    }

    openLinkEditor(
      { top: coords.bottom + 8, left: coords.left },
      { href: existingHref, text, from, to }
    );
  }, [view, openLinkEditor]);

  // 撤销
  const handleUndo = useCallback(() => {
    if (!view) return;
    undo(view.state, view.dispatch);
    view.focus();
  }, [view]);

  // 重做
  const handleRedo = useCallback(() => {
    if (!view) return;
    redo(view.state, view.dispatch);
    view.focus();
  }, [view]);

  // 检查是否可以撤销/重做
  const canUndo = useMemo(() => {
    if (!view) return false;
    return undo(view.state);
  }, [view?.state]);

  const canRedo = useMemo(() => {
    if (!view) return false;
    return redo(view.state);
  }, [view?.state]);

  // 工具栏按钮组
  const buttonGroups = useMemo(
    () => [
      // 历史操作
      [
        {
          name: 'undo',
          icon: Undo,
          title: t.documentEditor.actions.undo,
          action: handleUndo,
          disabled: !canUndo,
        },
        {
          name: 'redo',
          icon: Redo,
          title: t.documentEditor.actions.redo,
          action: handleRedo,
          disabled: !canRedo,
        },
      ],
      // 标题
      [
        {
          name: 'heading1',
          icon: Heading1,
          title: t.documentEditor.actions.heading1,
          action: () => setBlockTypeAction('heading', { level: 1 }),
          isActive: () => isNodeActive('heading', { level: 1 }),
        },
        {
          name: 'heading2',
          icon: Heading2,
          title: t.documentEditor.actions.heading2,
          action: () => setBlockTypeAction('heading', { level: 2 }),
          isActive: () => isNodeActive('heading', { level: 2 }),
        },
        {
          name: 'heading3',
          icon: Heading3,
          title: t.documentEditor.actions.heading3,
          action: () => setBlockTypeAction('heading', { level: 3 }),
          isActive: () => isNodeActive('heading', { level: 3 }),
        },
      ],
      // 文本格式
      [
        {
          name: 'bold',
          icon: Bold,
          title: t.documentEditor.actions.bold,
          action: () => toggleMarkAction('bold'),
          isActive: () => isMarkActive('bold'),
        },
        {
          name: 'italic',
          icon: Italic,
          title: t.documentEditor.actions.italic,
          action: () => toggleMarkAction('italic'),
          isActive: () => isMarkActive('italic'),
        },
        {
          name: 'underline',
          icon: UnderlineIcon,
          title: t.documentEditor.actions.underline,
          action: () => toggleMarkAction('underline'),
          isActive: () => isMarkActive('underline'),
        },
        {
          name: 'strike',
          icon: Strikethrough,
          title: t.documentEditor.actions.strike,
          action: () => toggleMarkAction('strike'),
          isActive: () => isMarkActive('strike'),
        },
        {
          name: 'code',
          icon: Code,
          title: t.documentEditor.actions.code,
          action: () => toggleMarkAction('code'),
          isActive: () => isMarkActive('code'),
        },
        {
          name: 'highlight',
          icon: Highlighter,
          title: t.documentEditor.actions.highlight,
          action: () => toggleMarkAction('highlight'),
          isActive: () => isMarkActive('highlight'),
        },
        {
          name: 'link',
          icon: Link2,
          title: t.documentEditor.actions.link,
          action: handleLinkClick,
          isActive: () => isMarkActive('link'),
        },
      ],
      // 列表和块
      [
        {
          name: 'bulletList',
          icon: List,
          title: t.documentEditor.actions.bulletList,
          action: () => wrapInListAction('bulletList'),
          isActive: () => isNodeActive('bulletList'),
        },
        {
          name: 'orderedList',
          icon: ListOrdered,
          title: t.documentEditor.actions.orderedList,
          action: () => wrapInListAction('orderedList'),
          isActive: () => isNodeActive('orderedList'),
        },
        {
          name: 'blockquote',
          icon: Quote,
          title: t.documentEditor.actions.blockquote,
          action: wrapInBlockquote,
          isActive: () => isNodeActive('blockquote'),
        },
        {
          name: 'horizontalRule',
          icon: Minus,
          title: t.documentEditor.actions.horizontalRule,
          action: insertHorizontalRule,
        },
      ],
    ],
    [
      handleUndo,
      handleRedo,
      canUndo,
      canRedo,
      setBlockTypeAction,
      toggleMarkAction,
      handleLinkClick,
      wrapInListAction,
      wrapInBlockquote,
      insertHorizontalRule,
      isMarkActive,
      isNodeActive,
      t,
    ]
  );

  return (
    <div
      className={cn(
        'toolbar flex flex-wrap items-center gap-1 border-b border-gray-200 bg-gray-50 px-2 py-1.5',
        className
      )}
    >
      {buttonGroups.map((group, groupIndex) => (
        <React.Fragment key={groupIndex}>
          {groupIndex > 0 && <div className="mx-1 h-6 w-px bg-gray-300" />}
          <div className="flex items-center gap-0.5">
            {group.map((button) => {
              const Icon = button.icon;
              const isActive = button.isActive?.();
              const isDisabled = 'disabled' in button ? button.disabled : false;

              return (
                <button
                  key={button.name}
                  type="button"
                  title={button.title}
                  onClick={button.action}
                  disabled={isDisabled}
                  className={cn(
                    'flex h-8 w-8 items-center justify-center rounded transition-colors',
                    isActive
                      ? 'bg-blue-100 text-blue-700'
                      : 'text-gray-600 hover:bg-gray-200 hover:text-gray-900',
                    isDisabled && 'cursor-not-allowed opacity-40'
                  )}
                >
                  <Icon className="h-4 w-4" />
                </button>
              );
            })}
          </div>
        </React.Fragment>
      ))}
    </div>
  );
}

export default Toolbar;
