import { useEffect, useState, useCallback, useMemo, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Button, Input, Space, message, Spin } from 'antd';
import {
  ArrowLeftOutlined,
  SaveOutlined,
  SendOutlined,
  SettingOutlined,
} from '@ant-design/icons';
import { Editor } from '@wangeditor/editor-for-react';
import { createToolbar } from '@wangeditor/editor';
import type { IDomEditor, IEditorConfig, IToolbarConfig, Toolbar as ToolbarType } from '@wangeditor/editor';
import {
  articleApi,
  articleCategoryApi,
  articleTagApi,
  type Article,
  type ArticleTagItem,
} from '../../../api/health/articles';
import { useThemeMode } from '../../../hooks/useThemeMode';
import { AuthButton } from '../../../components/AuthButton';
import { handleApiError } from '../../../api/client';
import { uploadFile } from '../../../api/upload';
import ArticleStyleLibrary from './ArticleStyleLibrary';
import ArticlePhonePreview from './ArticlePhonePreview';
import ArticleSettingsDrawer from './ArticleSettingsDrawer';
import { registerStyledBlockPlugin } from './styledBlockPlugin';
import '@wangeditor/editor/dist/css/style.css';

// 在任何编辑器实例创建之前注册自定义模块
registerStyledBlockPlugin();

export default function ArticleEditor() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const isEdit = Boolean(id);
  const isDark = useThemeMode();

  // 表单状态
  const [title, setTitle] = useState('');
  const [summary, setSummary] = useState('');
  const [content, setContent] = useState('');
  const [coverImage, setCoverImage] = useState('');
  const [slug, setSlug] = useState('');
  const [categoryId, setCategoryId] = useState<string | undefined>(undefined);
  const [selectedTagIds, setSelectedTagIds] = useState<string[]>([]);
  const [sortOrder, setSortOrder] = useState(0);
  const [isPublic, setIsPublic] = useState(true);
  const [version, setVersion] = useState(0);

  // 选项数据
  const [categories, setCategories] = useState<{ id: string; name: string }[]>([]);
  const [tags, setTags] = useState<ArticleTagItem[]>([]);

  // UI 状态
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [editor, setEditor] = useState<IDomEditor | null>(null);
  const [settingsDrawerOpen, setSettingsDrawerOpen] = useState(false);
  const [selectedThemeId, setSelectedThemeId] = useState('red');
  const [previewContent, setPreviewContent] = useState('');

  // 命令式 toolbar
  const toolbarContainerRef = useRef<HTMLDivElement>(null);
  const toolbarInstanceRef = useRef<ToolbarType | null>(null);

  // 防抖预览内容
  useEffect(() => {
    const timer = setTimeout(() => setPreviewContent(content), 300);
    return () => clearTimeout(timer);
  }, [content]);

  // 加载分类和标签
  useEffect(() => {
    const fetchOptions = async () => {
      try {
        const [cats, tagList] = await Promise.all([
          articleCategoryApi.list(),
          articleTagApi.list(),
        ]);
        setCategories(cats.map((c) => ({ id: c.id, name: c.name })));
        setTags(tagList);
      } catch {
        // 选项加载失败不阻塞
      }
    };
    fetchOptions();
  }, []);

  // 编辑模式：加载现有文章
  useEffect(() => {
    if (!id) return;
    const fetchArticle = async () => {
      setLoading(true);
      try {
        const article: Article = await articleApi.get(id);
        setTitle(article.title);
        setSummary(article.summary || '');
        setContent(article.content || '');
        setCoverImage(article.cover_image || '');
        setSlug(article.slug || '');
        setCategoryId(article.category_id);
        setSelectedTagIds(article.tags?.map((t) => t.id).filter(Boolean) || []);
        setSortOrder(article.sort_order);
        setIsPublic(article.is_public ?? true);
        setVersion(article.version);
      } catch {
        message.error('加载文章失败');
        navigate('/health/articles');
      } finally {
        setLoading(false);
      }
    };
    fetchArticle();
  }, [id, navigate]);

  // 编辑器配置
  const toolbarConfig = useMemo<Partial<IToolbarConfig>>(
    () => ({
      excludeKeys: [
        'group-video',
        'insertLink',
        'editLink',
        'unLink',
        'viewLink',
        'codeView',
      ],
    }),
    [],
  );

  const editorConfig = useMemo<Partial<IEditorConfig>>(
    () => ({
      placeholder: '请输入文章内容...',
      MENU_CONF: {
        uploadImage: {
          async customUpload(file: File, insertFn: (url: string, alt?: string, href?: string) => void) {
            try {
              const result = await uploadFile(file);
              const url: string = result.url;
              const token = localStorage.getItem('access_token');
              const urlWithToken = token ? `${url}?token=${token}` : url;
              insertFn(urlWithToken, file.name, urlWithToken);
            } catch {
              message.error('图片上传失败');
            }
          },
        },
      },
    }),
    [],
  );

  // toolbar 生命周期
  useEffect(() => {
    if (!editor || !toolbarContainerRef.current) return;
    if (toolbarInstanceRef.current) {
      toolbarInstanceRef.current.destroy();
      toolbarInstanceRef.current = null;
    }
    toolbarInstanceRef.current = createToolbar({
      editor,
      selector: toolbarContainerRef.current,
      config: toolbarConfig,
      mode: 'default',
    });
    return () => {
      if (toolbarInstanceRef.current) {
        toolbarInstanceRef.current.destroy();
        toolbarInstanceRef.current = null;
      }
    };
  }, [editor, toolbarConfig]);

  useEffect(() => {
    return () => {
      if (toolbarInstanceRef.current) {
        toolbarInstanceRef.current.destroy();
        toolbarInstanceRef.current = null;
      }
    };
  }, []);

  // 插入模板
  const handleInsertTemplate = useCallback(
    (html: string) => {
      if (!editor) {
        message.warning('请先点击编辑器获取焦点');
        return;
      }
      editor.restoreSelection();

      // 解析模板 HTML 提取 style 和 innerHtml
      const temp = document.createElement('div');
      temp.innerHTML = html;
      const el = temp.firstElementChild as HTMLElement | null;

      try {
        if (el && el.getAttribute('data-w-e-type') === 'styled-block') {
          editor.insertNode({
            type: 'styled-block',
            style: el.getAttribute('style') || '',
            innerHtml: el.innerHTML,
            children: [{ text: '' }],
          // eslint-disable-next-line @typescript-eslint/no-explicit-any -- wangEditor custom element type not in Slate types
          } as any);
        } else {
          editor.dangerouslyInsertHtml(html);
        }
      } catch (err) {
        console.error('[styled-block insert error]', err);
        editor.dangerouslyInsertHtml(html);
      }
    },
    [editor],
  );

  const handleSave = useCallback(async () => {
    if (!title.trim()) {
      message.warning('请输入文章标题');
      return;
    }
    setSaving(true);
    try {
      if (isEdit && id) {
        await articleApi.update(id, {
          title,
          summary: summary || undefined,
          content,
          cover_image: coverImage || undefined,
          slug: slug || undefined,
          category_id: categoryId,
          tag_ids: selectedTagIds.filter(Boolean),
          sort_order: sortOrder,
          is_public: isPublic,
          version,
        });
        message.success('文章已保存');
        const updated = await articleApi.get(id);
        setVersion(updated.version);
      } else {
        await articleApi.create({
          title,
          summary: summary || undefined,
          content,
          cover_image: coverImage || undefined,
          slug: slug || undefined,
          category_id: categoryId,
          tag_ids: selectedTagIds.filter(Boolean),
          sort_order: sortOrder,
          is_public: isPublic,
        });
        message.success('文章已创建');
        navigate('/health/articles');
      }
    } catch (err: unknown) {
      handleApiError(err, '保存失败');
    } finally {
      setSaving(false);
    }
  }, [
    id, isEdit, title, summary, content, coverImage, slug, categoryId,
    selectedTagIds, sortOrder, isPublic, version, navigate,
  ]);

  const handleSubmit = useCallback(async () => {
    if (!title.trim()) {
      message.warning('请输入文章标题');
      return;
    }
    setSaving(true);
    try {
      let currentVersion = version;
      if (isEdit && id) {
        await articleApi.update(id, {
          title,
          summary: summary || undefined,
          content,
          cover_image: coverImage || undefined,
          slug: slug || undefined,
          category_id: categoryId,
          tag_ids: selectedTagIds.filter(Boolean),
          sort_order: sortOrder,
          is_public: isPublic,
          version,
        });
        const updated = await articleApi.get(id);
        currentVersion = updated.version;
        setVersion(updated.version);
      } else {
        const created = await articleApi.create({
          title,
          summary: summary || undefined,
          content,
          cover_image: coverImage || undefined,
          slug: slug || undefined,
          category_id: categoryId,
          tag_ids: selectedTagIds.filter(Boolean),
          sort_order: sortOrder,
          is_public: isPublic,
        });
        currentVersion = created.version;
        setVersion(created.version);
        await articleApi.submit(created.id, currentVersion);
        message.success('已提交审核');
        navigate('/health/articles');
        return;
      }
      if (id) {
        await articleApi.submit(id, currentVersion);
      }
      message.success('已提交审核');
      navigate('/health/articles');
    } catch (err: unknown) {
      handleApiError(err, '提交审核失败');
    } finally {
      setSaving(false);
    }
  }, [
    id, isEdit, title, summary, content, coverImage, slug, categoryId,
    selectedTagIds, sortOrder, isPublic, version, navigate,
  ]);

  if (loading) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', padding: 100 }}>
        <Spin size="large" />
      </div>
    );
  }

  const borderColor = isDark ? '#1e293b' : '#f1f5f9';
  const bgPrimary = isDark ? '#111827' : '#FFFFFF';
  const bgSecondary = isDark ? '#0f172a' : '#f8fafc';

  return (
    <div>
      {/* 页面标题栏 */}
      <div className="erp-page-header">
        <Space size={12}>
          <Button
            type="text"
            icon={<ArrowLeftOutlined />}
            onClick={() => navigate('/health/articles')}
          />
          <h4 style={{ margin: 0 }}>{isEdit ? '编辑文章' : '新建文章'}</h4>
        </Space>
        <Space size={8}>
          <Button
            icon={<SettingOutlined />}
            onClick={() => setSettingsDrawerOpen(true)}
          >
            设置
          </Button>
          <AuthButton code="health.articles.manage">
            <Button icon={<SaveOutlined />} onClick={handleSave} loading={saving}>
              保存草稿
            </Button>
          </AuthButton>
          <AuthButton code="health.articles.manage">
            <Button
              type="primary"
              icon={<SendOutlined />}
              onClick={handleSubmit}
              loading={saving}
            >
              提交审核
            </Button>
          </AuthButton>
        </Space>
      </div>

      {/* 三栏布局 */}
      <div style={{ display: 'flex', height: 'calc(100vh - 120px)', gap: 0 }}>
        {/* 左栏：样式组件库 */}
        <ArticleStyleLibrary
          isDark={isDark}
          onInsertTemplate={handleInsertTemplate}
          selectedTheme={selectedThemeId}
          onThemeChange={setSelectedThemeId}
        />

        {/* 中间：标题 + 工具栏 + 编辑器 */}
        <div
          key={id ?? 'new'}
          style={{
            flex: 1,
            display: 'flex',
            flexDirection: 'column',
            background: bgPrimary,
            overflow: 'hidden',
          }}
        >
          {/* 标题输入 — Notion 风格大字 */}
          <div
            style={{
              padding: '16px 24px 8px',
              borderBottom: `1px solid ${borderColor}`,
            }}
          >
            <Input
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="请输入文章标题..."
              variant="borderless"
              maxLength={200}
              style={{
                fontSize: 28,
                fontWeight: 700,
                color: isDark ? '#e2e8f0' : '#1e293b',
                padding: 0,
                lineHeight: 1.4,
              }}
            />
          </div>

          {/* 工具栏 */}
          <div
            ref={toolbarContainerRef}
            style={{
              borderBottom: `1px solid ${borderColor}`,
              background: bgSecondary,
              zIndex: 100,
            }}
          />

          {/* 编辑器 */}
          <div style={{ flex: 1, overflowY: 'auto' }}>
            <Editor
              defaultConfig={editorConfig}
              value={content}
              onCreated={setEditor}
              onChange={(editorInstance) => setContent(editorInstance.getHtml())}
              mode="default"
              style={{
                minHeight: 400,
                background: bgPrimary,
                color: isDark ? '#e2e8f0' : '#1e293b',
              }}
            />
          </div>
        </div>

        {/* 右栏：手机预览 */}
        <ArticlePhonePreview
          title={title}
          content={previewContent}
          category={categories.find((c) => c.id === categoryId)?.name}
          summary={summary}
          coverImage={coverImage}
          isDark={isDark}
        />
      </div>

      {/* 设置抽屉 */}
      <ArticleSettingsDrawer
        open={settingsDrawerOpen}
        onClose={() => setSettingsDrawerOpen(false)}
        isDark={isDark}
        summary={summary}
        onSummaryChange={setSummary}
        coverImage={coverImage}
        onCoverImageChange={setCoverImage}
        categoryId={categoryId}
        onCategoryChange={setCategoryId}
        selectedTagIds={selectedTagIds}
        onTagIdsChange={setSelectedTagIds}
        slug={slug}
        onSlugChange={setSlug}
        sortOrder={sortOrder}
        onSortOrderChange={setSortOrder}
        isPublic={isPublic}
        onIsPublicChange={setIsPublic}
        categories={categories}
        tags={tags}
      />
    </div>
  );
}
