/**
 * EventFormModal - 通用事件表单弹窗组件 (Ant Design 重构版)
 * 用于新建/编辑投资计划、复盘
 *
 * 功能特性：
 * - 使用 Ant Design 组件
 * - 简化字段：标题、日期、描述、关联股票
 * - 计划/复盘模板系统
 * - 股票多选组件带智能搜索
 * - Ctrl + Enter 快捷键保存
 */

import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import {
  Modal,
  Form,
  Input,
  DatePicker,
  Select,
  Button,
  Tag,
  Divider,
  message,
  Space,
  Spin,
} from 'antd';
import type { SelectProps } from 'antd';
import {
  BulbOutlined,
  StarOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import { useSelector } from 'react-redux';

import { useAppDispatch } from '@/store/hooks';
import { usePlanningData } from './PlanningContext';
import './EventFormModal.less';
import type { InvestmentEvent, EventType } from '@/types';
import { logger } from '@/utils/logger';
import { getApiBase } from '@/utils/apiConfig';
import { loadWatchlist, loadAllStocks } from '@/store/slices/stockSlice';
import { stockService } from '@/services/stockService';

dayjs.locale('zh-cn');

const { TextArea } = Input;

/**
 * 股票选项接口
 */
interface StockOption {
  value: string;
  label: string;
  stock_code: string;
  stock_name: string;
}

/**
 * 表单数据接口
 */
interface FormData {
  title: string;
  date: dayjs.Dayjs;
  content: string;
  stocks: string[];
}

/**
 * 模板类型
 */
interface Template {
  label: string;
  content: string;
}

/**
 * 计划模板
 */
const PLAN_TEMPLATES: Template[] = [
  {
    label: '目标',
    content: '【投资目标】\n\n',
  },
  {
    label: '策略',
    content: '【交易策略】\n\n',
  },
  {
    label: '风险控制',
    content: '【风险控制】\n- 止损位：\n- 仓位控制：\n',
  },
  {
    label: '时间规划',
    content: '【时间规划】\n- 建仓时机：\n- 持仓周期：\n',
  },
];

/**
 * 复盘模板
 */
const REVIEW_TEMPLATES: Template[] = [
  {
    label: '操作回顾',
    content: '【操作回顾】\n- 买入操作：\n- 卖出操作：\n',
  },
  {
    label: '盈亏分析',
    content: '【盈亏分析】\n- 盈亏金额：\n- 收益率：\n- 主要原因：\n',
  },
  {
    label: '经验总结',
    content: '【经验总结】\n- 做对的地方：\n- 做错的地方：\n',
  },
  {
    label: '后续调整',
    content: '【后续调整】\n- 策略调整：\n- 仓位调整：\n',
  },
];

/**
 * Redux state 类型
 */
interface RootState {
  stock: {
    watchlist: Array<{ stock_code: string; stock_name: string }>;
    allStocks: Array<{ code: string; name: string }>;
    loading: {
      watchlist: boolean;
      allStocks: boolean;
    };
  };
}

/**
 * EventFormModal Props
 */
export interface EventFormModalProps {
  /** 弹窗是否打开 */
  isOpen: boolean;
  /** 关闭弹窗回调 */
  onClose: () => void;
  /** 模式：新建或编辑 */
  mode: 'create' | 'edit';
  /** 事件类型（新建时使用） */
  eventType?: EventType;
  /** 初始日期（新建时使用，如从日历点击） */
  initialDate?: string;
  /** 编辑时的原始事件数据 */
  editingEvent?: InvestmentEvent | null;
  /** 保存成功回调 */
  onSuccess: () => void;
  /** 主题颜色 */
  colorScheme?: string;
  /** 显示标签（如 "计划"、"复盘"、"事件"） */
  label?: string;
  /** 是否显示日期选择器 */
  showDatePicker?: boolean;
  /** 是否显示类型选择 */
  showTypeSelect?: boolean;
  /** 是否显示状态选择 */
  showStatusSelect?: boolean;
  /** 是否显示重要度选择 */
  showImportance?: boolean;
  /** 是否显示标签输入 */
  showTags?: boolean;
  /** 股票输入方式：'tag' 为标签形式，'text' 为逗号分隔文本 */
  stockInputMode?: 'tag' | 'text';
  /** API 端点 */
  apiEndpoint?: 'investment-plans' | 'calendar/events';
}

/**
 * EventFormModal 组件
 */
export const EventFormModal: React.FC<EventFormModalProps> = ({
  isOpen,
  onClose,
  mode,
  eventType = 'plan',
  initialDate,
  editingEvent,
  onSuccess,
  label = '事件',
  apiEndpoint = 'investment-plans',
}) => {
  const { loadAllData } = usePlanningData();
  const dispatch = useAppDispatch();
  const [form] = Form.useForm<FormData>();
  const [saving, setSaving] = useState(false);
  const [stockOptions, setStockOptions] = useState<StockOption[]>([]);
  const [searchText, setSearchText] = useState('');
  const modalContentRef = useRef<HTMLDivElement>(null);

  // 从 Redux 获取自选股和全部股票列表
  const watchlist = useSelector((state: RootState) => state.stock.watchlist);
  const allStocks = useSelector((state: RootState) => state.stock.allStocks);
  const watchlistLoading = useSelector((state: RootState) => state.stock.loading.watchlist);
  const allStocksLoading = useSelector((state: RootState) => state.stock.loading.allStocks);

  // 将自选股转换为 StockOption 格式
  const watchlistOptions = useMemo<StockOption[]>(() => {
    return watchlist.map(item => ({
      value: item.stock_code,
      label: `${item.stock_name}(${item.stock_code})`,
      stock_code: item.stock_code,
      stock_name: item.stock_name,
    }));
  }, [watchlist]);

  // 获取模板列表
  const templates = eventType === 'plan' ? PLAN_TEMPLATES : REVIEW_TEMPLATES;

  // 生成默认模板内容
  const getDefaultContent = (type: EventType): string => {
    const templateList = type === 'plan' ? PLAN_TEMPLATES : REVIEW_TEMPLATES;
    return templateList.map(t => t.content).join('\n');
  };

  // 弹窗打开时加载数据
  useEffect(() => {
    if (isOpen) {
      // 加载自选股列表
      dispatch(loadWatchlist());
      // 加载全部股票列表（用于模糊搜索）
      dispatch(loadAllStocks());
    }
  }, [isOpen, dispatch]);

  // 初始化表单数据
  useEffect(() => {
    if (isOpen) {
      if (mode === 'edit' && editingEvent) {
        // 将 stocks 转换为代码数组（兼容对象和字符串格式）
        const stockCodes = (editingEvent.stocks || []).map(stock =>
          typeof stock === 'string' ? stock : stock.code
        );
        form.setFieldsValue({
          title: editingEvent.title,
          date: dayjs(editingEvent.event_date || editingEvent.date),
          content: editingEvent.description || editingEvent.content || '',
          stocks: stockCodes,
        });
      } else {
        // 新建模式，重置表单并预填充模板内容
        form.resetFields();
        form.setFieldsValue({
          date: initialDate ? dayjs(initialDate) : dayjs(),
          stocks: [],
          content: getDefaultContent(eventType),
        });
      }
    }
  }, [isOpen, mode, editingEvent, initialDate, form, eventType]);

  // 股票搜索（前端模糊搜索）
  const handleStockSearch = useCallback((value: string) => {
    setSearchText(value);

    if (!value || value.length < 1) {
      // 无搜索词时显示自选股列表
      setStockOptions(watchlistOptions);
      return;
    }

    // 使用 stockService.fuzzySearch 进行前端模糊搜索
    const results = stockService.fuzzySearch(value, allStocks, 10);
    const options: StockOption[] = results.map(stock => ({
      value: stock.code,
      label: `${stock.name}(${stock.code})`,
      stock_code: stock.code,
      stock_name: stock.name,
    }));

    setStockOptions(options.length > 0 ? options : watchlistOptions);
  }, [allStocks, watchlistOptions]);

  // 保存数据
  const handleSave = useCallback(async (): Promise<void> => {
    try {
      const values = await form.validateFields();
      setSaving(true);

      const base = getApiBase();

      // 将选中的股票代码转换为包含名称的对象数组
      const stocksWithNames = (values.stocks || []).map((code: string) => {
        const stockInfo = allStocks.find(s => s.code === code);
        const watchlistInfo = watchlist.find(s => s.stock_code === code);
        return {
          code,
          name: stockInfo?.name || watchlistInfo?.stock_name || code,
        };
      });

      // 构建请求数据
      const requestData: Record<string, unknown> = {
        title: values.title,
        content: values.content,
        date: values.date.format('YYYY-MM-DD'),
        type: eventType,
        stocks: stocksWithNames,
        status: 'active',
      };

      // 根据 API 端点调整字段名
      if (apiEndpoint === 'calendar/events') {
        requestData.description = values.content;
        requestData.event_date = values.date.format('YYYY-MM-DD');
        delete requestData.content;
        delete requestData.date;
      }

      const url = mode === 'edit' && editingEvent
        ? `${base}/api/account/${apiEndpoint}/${editingEvent.id}`
        : `${base}/api/account/${apiEndpoint}`;

      const method = mode === 'edit' ? 'PUT' : 'POST';

      const response = await fetch(url, {
        method,
        headers: {
          'Content-Type': 'application/json',
        },
        credentials: 'include',
        body: JSON.stringify(requestData),
      });

      if (response.ok) {
        logger.info('EventFormModal', `${mode === 'edit' ? '更新' : '创建'}${label}成功`, {
          itemId: editingEvent?.id,
          title: values.title,
        });
        message.success(mode === 'edit' ? '修改成功' : '添加成功');
        onClose();
        onSuccess();
        loadAllData();
      } else {
        throw new Error('保存失败');
      }
    } catch (error) {
      if (error instanceof Error && error.message !== '保存失败') {
        // 表单验证错误，不显示额外提示
        return;
      }
      logger.error('EventFormModal', 'handleSave', error, {
        itemId: editingEvent?.id,
      });
      message.error('保存失败，请稍后重试');
    } finally {
      setSaving(false);
    }
  }, [form, eventType, apiEndpoint, mode, editingEvent, label, onClose, onSuccess, loadAllData, allStocks, watchlist]);

  // 监听键盘快捷键 Ctrl + Enter
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (isOpen && (e.ctrlKey || e.metaKey) && e.key === 'Enter') {
        e.preventDefault();
        handleSave();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, handleSave]);

  // 插入模板
  const handleInsertTemplate = (template: Template): void => {
    const currentContent = form.getFieldValue('content') || '';
    const newContent = currentContent
      ? `${currentContent}\n\n${template.content}`
      : template.content;
    form.setFieldsValue({ content: newContent });
  };

  // 获取标题 placeholder
  const getTitlePlaceholder = (): string => {
    if (eventType === 'plan') {
      return '例如：关注AI板块';
    }
    return '例如：12月操作总结';
  };

  // 获取内容 placeholder
  const getContentPlaceholder = (): string => {
    if (eventType === 'plan') {
      return '计划模板:\n目标:\n策略:\n风险控制:\n时间规划:';
    }
    return '复盘模板:\n操作回顾:\n盈亏分析:\n经验总结:\n后续调整:';
  };

  // 判断是否显示自选股列表
  const isShowingWatchlist = !searchText && stockOptions === watchlistOptions;

  // 股票选择器选项配置
  const selectProps: SelectProps<string[]> = {
    mode: 'multiple',
    placeholder: allStocksLoading ? '加载股票列表中...' : '输入股票代码或名称搜索',
    filterOption: false,
    onSearch: handleStockSearch,
    loading: watchlistLoading || allStocksLoading,
    notFoundContent: allStocksLoading ? (
      <div style={{ textAlign: 'center', padding: '8px' }}>
        <Spin size="small" />
        <span style={{ marginLeft: 8 }}>加载中...</span>
      </div>
    ) : '暂无结果',
    options: stockOptions,
    onFocus: () => {
      if (stockOptions.length === 0) {
        setStockOptions(watchlistOptions);
      }
    },
    tagRender: (props) => {
      const { label: tagLabel, closable, onClose: onTagClose } = props;
      return (
        <Tag
          color="blue"
          closable={closable}
          onClose={onTagClose}
          style={{ marginRight: 3 }}
        >
          {tagLabel}
        </Tag>
      );
    },
    popupRender: (menu) => (
      <>
        {isShowingWatchlist && watchlistOptions.length > 0 && (
          <>
            <div style={{ padding: '4px 8px 0' }}>
              <span style={{ fontSize: 12, color: '#999' }}>
                <StarOutlined style={{ marginRight: 4, color: '#faad14' }} />
                我的自选股
              </span>
            </div>
            <Divider style={{ margin: '4px 0 0' }} />
          </>
        )}
        {menu}
        {!isShowingWatchlist && searchText && (
          <>
            <Divider style={{ margin: '8px 0' }} />
            <div style={{ padding: '0 8px 4px' }}>
              <span style={{ fontSize: 12, color: '#999' }}>
                <BulbOutlined style={{ marginRight: 4 }} />
                搜索结果（输入代码或名称）
              </span>
            </div>
          </>
        )}
      </>
    ),
  };

  // 获取按钮文案
  const getButtonText = (): string => {
    if (mode === 'edit') {
      return eventType === 'plan' ? '更新计划' : '更新复盘';
    }
    return eventType === 'plan' ? '创建计划' : '创建复盘';
  };

  return (
    <Modal
      title={`${mode === 'edit' ? '编辑' : '新建'}${eventType === 'plan' ? '投资计划' : '复盘'}`}
      open={isOpen}
      onCancel={onClose}
      width={600}
      destroyOnClose
      maskClosable={true}
      keyboard
      className="event-form-modal"
      footer={
        <div className="modal-footer">
          <Button
            type="primary"
            onClick={handleSave}
            loading={saving}
            disabled={saving}
          >
            {getButtonText()}
          </Button>
        </div>
      }
    >
      <div ref={modalContentRef}>
        {isOpen && <Form
          form={form}
          layout="horizontal"
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 20 }}
          labelAlign="left"
          requiredMark={false}
          initialValues={{
            date: dayjs(),
            stocks: [],
          }}
        >
          {/* 标题 */}
          <Form.Item
            name="title"
            label={<span style={{ fontWeight: 600 }}>标题 <span style={{ color: '#ff4d4f' }}>*</span></span>}
            rules={[
              { required: true, message: '请输入标题' },
              { max: 50, message: '标题不能超过50个字符' },
            ]}
          >
            <Input
              placeholder={getTitlePlaceholder()}
              maxLength={50}
              showCount
            />
          </Form.Item>

          {/* 日期 */}
          <Form.Item
            name="date"
            label={<span style={{ fontWeight: 600 }}>{eventType === 'plan' ? '计划日期' : '复盘日期'} <span style={{ color: '#ff4d4f' }}>*</span></span>}
            rules={[{ required: true, message: '请选择日期' }]}
          >
            <DatePicker
              style={{ width: '100%' }}
              format="YYYY-MM-DD"
              placeholder="选择日期"
              allowClear={false}
            />
          </Form.Item>

          {/* 描述/内容 - 上下布局 */}
          <Form.Item
            name="content"
            label={<span style={{ fontWeight: 600 }}>{eventType === 'plan' ? '计划详情' : '复盘内容'} <span style={{ color: '#ff4d4f' }}>*</span></span>}
            rules={[{ required: true, message: '请输入内容' }]}
            labelCol={{ span: 24 }}
            wrapperCol={{ span: 24 }}
            style={{ marginBottom: 8 }}
          >
            <TextArea
              placeholder={getContentPlaceholder()}
              rows={8}
              showCount
              maxLength={2000}
              style={{ resize: 'vertical' }}
            />
          </Form.Item>

          {/* 模板快捷按钮 - 独立放置在 Form.Item 外部 */}
          <div style={{ marginBottom: 24 }}>
            <Space wrap size="small" className="template-buttons">
              {templates.map((template) => (
                <Button
                  key={template.label}
                  size="small"
                  onClick={() => handleInsertTemplate(template)}
                >
                  {template.label}
                </Button>
              ))}
            </Space>
          </div>

          {/* 关联股票 */}
          <Form.Item
            name="stocks"
            label={<span style={{ fontWeight: 600 }}>关联股票</span>}
          >
            <Select {...selectProps} />
          </Form.Item>
        </Form>}
      </div>
    </Modal>
  );
};

export default EventFormModal;
