'use client';

import { useState, useMemo, useCallback, memo } from 'react';
import { Table, Input, Select, Button, Card, Space, message, Modal, Descriptions, Spin } from 'antd';
import { SearchOutlined, EyeOutlined } from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import { VideoAnalysisData } from '@/types';
import { searchVideos, VideoListItem, getVideoAnalysis } from '@/lib/api';

// 搜索类型选项
type SearchType = 'star_id' | 'unique_id' | 'nickname';

const SEARCH_TYPE_OPTIONS = [
  { value: 'star_id' as SearchType, label: '星图ID' },
  { value: 'unique_id' as SearchType, label: '达人unique_id' },
  { value: 'nickname' as SearchType, label: '达人昵称' },
];

const SEARCH_PLACEHOLDER: Record<SearchType, string> = {
  star_id: '请输入星图ID',
  unique_id: '请输入达人unique_id',
  nickname: '请输入达人昵称关键词',
};

// 格式化数字（千分位，保留2位小数）
function formatNumber(num: number | null | undefined): string {
  if (num === null || num === undefined) return '-';
  return num.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

// 格式化整数（千分位）
function formatInt(num: number | null | undefined): string {
  if (num === null || num === undefined) return '-';
  return Math.round(num).toLocaleString('zh-CN');
}

// 详情弹窗组件 - 使用 memo 避免不必要的重渲染
const DetailModal = memo(function DetailModal({
  visible,
  data,
  loading,
  onClose,
}: {
  visible: boolean;
  data: VideoAnalysisData | null;
  loading: boolean;
  onClose: () => void;
}) {
  return (
    <Modal
      title="视频详情"
      open={visible}
      onCancel={onClose}
      footer={null}
      width={900}
      styles={{ body: { maxHeight: '70vh', overflowY: 'auto', userSelect: 'text', WebkitUserSelect: 'text' } }}
    >
      {loading ? (
        <div style={{ textAlign: 'center', padding: 50 }}>
          <Spin size="large" />
        </div>
      ) : data ? (
        <Space direction="vertical" size="middle" style={{ width: '100%', userSelect: 'text', WebkitUserSelect: 'text' } as React.CSSProperties}>
          {/* 基础信息 */}
          <Descriptions title="基础信息" bordered size="small" column={2} contentStyle={{ userSelect: 'text', cursor: 'text' }}>
            <Descriptions.Item label="达人昵称"><span style={{ userSelect: 'text' }}>{data.base_info.star_nickname || '-'}</span></Descriptions.Item>
            <Descriptions.Item label="达人unique_id"><span style={{ userSelect: 'text' }}>{data.base_info.star_unique_id || '-'}</span></Descriptions.Item>
            <Descriptions.Item label="视频ID">{data.base_info.vid || '-'}</Descriptions.Item>
            <Descriptions.Item label="发布时间">{data.base_info.create_date || '-'}</Descriptions.Item>
            <Descriptions.Item label="爆文类型">{data.base_info.hot_type || '-'}</Descriptions.Item>
            <Descriptions.Item label="合作行业">{data.base_info.industry_id || '-'}</Descriptions.Item>
            <Descriptions.Item label="合作品牌">{data.base_info.brand_name || data.base_info.brand_id || '-'}</Descriptions.Item>
            <Descriptions.Item label="视频标题" span={2}>
              {data.base_info.video_url ? (
                <a href={data.base_info.video_url} target="_blank" rel="noopener noreferrer">
                  {data.base_info.title || '查看视频'}
                </a>
              ) : (
                data.base_info.title || '-'
              )}
            </Descriptions.Item>
          </Descriptions>

          {/* 触达指标 */}
          <Descriptions title="触达指标" bordered size="small" column={4} contentStyle={{ userSelect: 'text', cursor: 'text' }}>
            <Descriptions.Item label="自然曝光数">{formatInt(data.reach_metrics.natural_play_cnt)}</Descriptions.Item>
            <Descriptions.Item label="加热曝光数">{formatInt(data.reach_metrics.heated_play_cnt)}</Descriptions.Item>
            <Descriptions.Item label="总曝光数">{formatInt(data.reach_metrics.total_play_cnt)}</Descriptions.Item>
            <Descriptions.Item label="总互动">{formatInt(data.reach_metrics.total_interaction_cnt)}</Descriptions.Item>
            <Descriptions.Item label="点赞">{formatInt(data.reach_metrics.digg_cnt)}</Descriptions.Item>
            <Descriptions.Item label="转发">{formatInt(data.reach_metrics.share_cnt)}</Descriptions.Item>
            <Descriptions.Item label="评论">{formatInt(data.reach_metrics.comment_cnt)}</Descriptions.Item>
          </Descriptions>

          {/* A3指标 */}
          <Descriptions title="A3指标" bordered size="small" column={3} contentStyle={{ userSelect: 'text', cursor: 'text' }}>
            <Descriptions.Item label="新增A3">{formatInt(data.a3_metrics.total_new_a3_cnt)}</Descriptions.Item>
            <Descriptions.Item label="加热新增A3">{formatInt(data.a3_metrics.heated_new_a3_cnt)}</Descriptions.Item>
            <Descriptions.Item label="自然新增A3">{formatInt(data.a3_metrics.natural_new_a3_cnt)}</Descriptions.Item>
          </Descriptions>

          {/* 搜索指标 */}
          <Descriptions title="搜索指标" bordered size="small" column={3} contentStyle={{ userSelect: 'text', cursor: 'text' }}>
            <Descriptions.Item label="回搜人数">{formatInt(data.search_metrics.back_search_uv)}</Descriptions.Item>
            <Descriptions.Item label="回搜次数">{formatInt(data.search_metrics.back_search_cnt)}</Descriptions.Item>
            <Descriptions.Item label="看后搜人数">{formatInt(data.search_metrics.after_view_search_uv)}</Descriptions.Item>
            <Descriptions.Item label="看后搜次数">{formatInt(data.search_metrics.after_view_search_cnt)}</Descriptions.Item>
            <Descriptions.Item label="预估自然看后搜人数">{formatNumber(data.search_metrics.estimated_natural_search_uv)}</Descriptions.Item>
          </Descriptions>

          {/* 费用指标 */}
          <Descriptions title="费用指标" bordered size="small" column={3} contentStyle={{ userSelect: 'text', cursor: 'text' }}>
            <Descriptions.Item label="预估总费用">{formatNumber(data.cost_metrics.total_cost)}</Descriptions.Item>
            <Descriptions.Item label="预估加热费用">{formatNumber(data.cost_metrics.heated_cost)}</Descriptions.Item>
            <Descriptions.Item label="预估视频采买费用">{formatNumber(data.cost_metrics.estimated_video_cost)}</Descriptions.Item>
          </Descriptions>

          {/* 成本指标 */}
          <Descriptions title="成本指标" bordered size="small" column={3} contentStyle={{ userSelect: 'text', cursor: 'text' }}>
            <Descriptions.Item label="预估CPM">{formatNumber(data.calculated_metrics.estimated_cpm)}</Descriptions.Item>
            <Descriptions.Item label="预估自然CPM">{formatNumber(data.calculated_metrics.estimated_natural_cpm)}</Descriptions.Item>
            <Descriptions.Item label="预估CPA3">{formatNumber(data.calculated_metrics.estimated_cp_a3)}</Descriptions.Item>
            <Descriptions.Item label="预估自然CPA3">{formatNumber(data.calculated_metrics.estimated_natural_cp_a3)}</Descriptions.Item>
            <Descriptions.Item label="预估CPsearch">{formatNumber(data.calculated_metrics.estimated_cp_search)}</Descriptions.Item>
            <Descriptions.Item label="自然CPsearch">{formatNumber(data.calculated_metrics.estimated_natural_cp_search)}</Descriptions.Item>
          </Descriptions>
        </Space>
      ) : null}
    </Modal>
  );
});

export default function VideoAnalysis() {
  const [searchType, setSearchType] = useState<SearchType>('star_id');
  const [searchValue, setSearchValue] = useState('');
  const [loading, setLoading] = useState(false);
  const [listData, setListData] = useState<VideoListItem[]>([]);

  // 详情弹窗状态
  const [detailVisible, setDetailVisible] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detailData, setDetailData] = useState<VideoAnalysisData | null>(null);

  // 详情缓存 - 避免重复请求
  const [detailCache, setDetailCache] = useState<Record<string, VideoAnalysisData>>({});

  // 使用 useCallback 包裹搜索处理器
  const handleSearch = useCallback(async () => {
    if (!searchValue.trim()) {
      message.warning(`请输入${SEARCH_TYPE_OPTIONS.find(o => o.value === searchType)?.label}`);
      return;
    }

    setLoading(true);
    try {
      const response = await searchVideos({
        type: searchType,
        value: searchValue.trim(),
      });

      if (response.success) {
        setListData(response.data as VideoListItem[]);
        if ((response.data as VideoListItem[]).length === 0) {
          message.info('未找到相关视频');
        }
      } else {
        message.error(response.error || '搜索失败');
      }
    } catch (err) {
      message.error(err instanceof Error ? err.message : '搜索失败');
    } finally {
      setLoading(false);
    }
  }, [searchType, searchValue]);

  // 使用 useCallback 包裹详情查看处理器，带缓存逻辑
  const handleViewDetail = useCallback(async (itemId: string) => {
    // 检查缓存
    if (detailCache[itemId]) {
      setDetailData(detailCache[itemId]);
      setDetailVisible(true);
      return;
    }

    setDetailVisible(true);
    setDetailLoading(true);
    setDetailData(null);

    try {
      const response = await getVideoAnalysis(itemId);
      if (response.success) {
        setDetailData(response.data);
        // 缓存结果
        setDetailCache(prev => ({ ...prev, [itemId]: response.data }));
      } else {
        message.error(response.error || '获取详情失败');
        setDetailVisible(false);
      }
    } catch (err) {
      message.error(err instanceof Error ? err.message : '获取详情失败');
      setDetailVisible(false);
    } finally {
      setDetailLoading(false);
    }
  }, [detailCache]);

  // 关闭详情弹窗的回调
  const handleCloseDetail = useCallback(() => {
    setDetailVisible(false);
  }, []);

  // 使用 useMemo 包裹表格列定义，避免每次重建
  const columns: ColumnsType<VideoListItem> = useMemo(() => [
    {
      title: '达人昵称',
      dataIndex: 'star_nickname',
      key: 'star_nickname',
      width: 120,
      fixed: 'left',
      render: (text) => text || '-',
    },
    {
      title: '视频标题',
      dataIndex: 'title',
      key: 'title',
      width: 200,
      ellipsis: true,
      render: (text, record) =>
        record.video_url ? (
          <a href={record.video_url} target="_blank" rel="noopener noreferrer">
            {text || '查看视频'}
          </a>
        ) : (
          text || '-'
        ),
    },
    {
      title: '发布时间',
      dataIndex: 'create_date',
      key: 'create_date',
      width: 110,
      render: (text) => (text ? text.split('T')[0] : '-'),
    },
    {
      title: '爆文类型',
      dataIndex: 'hot_type',
      key: 'hot_type',
      width: 90,
      render: (text) => text || '-',
    },
    {
      title: '合作行业',
      dataIndex: 'industry_id',
      key: 'industry_id',
      width: 90,
      render: (text) => text || '-',
    },
    {
      title: '合作品牌',
      dataIndex: 'brand_name',
      key: 'brand_name',
      width: 100,
      render: (text) => text || '-',
    },
    {
      title: '新增A3',
      dataIndex: 'total_new_a3_cnt',
      key: 'total_new_a3_cnt',
      width: 90,
      align: 'right',
      render: (val) => formatInt(val),
    },
    {
      title: '加热A3',
      dataIndex: 'heated_new_a3_cnt',
      key: 'heated_new_a3_cnt',
      width: 90,
      align: 'right',
      render: (val) => formatInt(val),
    },
    {
      title: '自然A3',
      dataIndex: 'natural_new_a3_cnt',
      key: 'natural_new_a3_cnt',
      width: 90,
      align: 'right',
      render: (val) => formatInt(val),
    },
    {
      title: '预估自然CPM',
      dataIndex: 'estimated_natural_cpm',
      key: 'estimated_natural_cpm',
      width: 110,
      align: 'right',
      render: (val) => formatNumber(val),
    },
    {
      title: '预估CPA3',
      dataIndex: 'estimated_cp_a3',
      key: 'estimated_cp_a3',
      width: 100,
      align: 'right',
      render: (val) => formatNumber(val),
    },
    {
      title: '预估自然CPA3',
      dataIndex: 'estimated_natural_cp_a3',
      key: 'estimated_natural_cp_a3',
      width: 110,
      align: 'right',
      render: (val) => formatNumber(val),
    },
    {
      title: '预估CPsearch',
      dataIndex: 'estimated_cp_search',
      key: 'estimated_cp_search',
      width: 110,
      align: 'right',
      render: (val) => formatNumber(val),
    },
    {
      title: '自然CPsearch',
      dataIndex: 'estimated_natural_cp_search',
      key: 'estimated_natural_cp_search',
      width: 110,
      align: 'right',
      render: (val) => formatNumber(val),
    },
    {
      title: '操作',
      key: 'action',
      width: 80,
      fixed: 'right',
      render: (_, record) => (
        <Button
          type="link"
          icon={<EyeOutlined />}
          onClick={() => handleViewDetail(record.item_id)}
        >
          详情
        </Button>
      ),
    },
  ], [handleViewDetail]);

  return (
    <div style={{ padding: 24, maxWidth: 1600, margin: '0 auto' }}>
      {/* 搜索区域 */}
      <Card style={{ marginBottom: 24 }}>
        <h1 style={{ fontSize: 20, fontWeight: 'bold', marginBottom: 16 }}>KOL 视频分析</h1>
        <Space.Compact style={{ width: '100%', maxWidth: 600 }}>
          <Select
            value={searchType}
            onChange={(val) => {
              setSearchType(val);
              setSearchValue('');
            }}
            style={{ width: 140 }}
            options={SEARCH_TYPE_OPTIONS}
          />
          <Input
            value={searchValue}
            onChange={(e) => setSearchValue(e.target.value)}
            placeholder={SEARCH_PLACEHOLDER[searchType]}
            onPressEnter={handleSearch}
            style={{ flex: 1 }}
          />
          <Button
            type="primary"
            icon={<SearchOutlined />}
            onClick={handleSearch}
            loading={loading}
          >
            查询
          </Button>
        </Space.Compact>
      </Card>

      {/* 结果表格 - 启用虚拟滚动 */}
      <Card>
        <Table
          columns={columns}
          dataSource={listData}
          rowKey="item_id"
          loading={loading}
          virtual
          scroll={{ x: 1800, y: 600 }}
          pagination={{
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: (total) => `共 ${total} 条`,
          }}
          locale={{ emptyText: '暂无数据，请输入搜索条件' }}
        />
      </Card>

      {/* 详情弹窗 */}
      <DetailModal
        visible={detailVisible}
        data={detailData}
        loading={detailLoading}
        onClose={handleCloseDetail}
      />
    </div>
  );
}
