import { useEffect, useState } from 'react';
import { Button, List, Popconfirm, Input, App as AntApp, Tooltip, Empty, Segmented, Tag, Spin, Dropdown, Modal } from 'antd';
import dayjs from 'dayjs';
import { ChatSession, SearchHit, SessionAPI } from '../api';

interface Props {
  agentId: string;
  activeSessionId: string | null;
  onChange: (sessionId: string, options?: { highlightMessageId?: string }) => void;
  refreshTick?: number;
  theme?: 'light' | 'dark';
}

export default function SessionSidebar({ agentId, activeSessionId, onChange, refreshTick, theme = 'light' }: Props) {
  const { message } = AntApp.useApp();
  const [tab, setTab] = useState<'active' | 'archived'>('active');
  const [active, setActive] = useState<ChatSession[]>([]);
  const [archived, setArchived] = useState<ChatSession[]>([]);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editingTitle, setEditingTitle] = useState('');

  // 搜索
  const [searchQ, setSearchQ] = useState('');
  const [searching, setSearching] = useState(false);
  const [searchHits, setSearchHits] = useState<SearchHit[]>([]);
  const [searchSessionTitles, setSearchSessionTitles] = useState<{ id: string; title: string; archived: boolean }[]>([]);

  const load = async () => {
    const [a, ar] = await Promise.all([SessionAPI.list(agentId, '0'), SessionAPI.list(agentId, '1')]);
    setActive(a);
    setArchived(ar);
    // 自动选中
    if (!activeSessionId) {
      if (a.length === 0) {
        const created = await SessionAPI.create(agentId);
        setActive([created]);
        onChange(created.id);
      } else {
        onChange(a[0].id);
      }
    }
  };

  useEffect(() => {
    load();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [agentId, refreshTick]);

  const isDark = theme === 'dark';

  // Theme-aware colors
  const c = {
    text: isDark ? '#c8c8d8' : '#1f2330',
    textDim: isDark ? '#8b8ba0' : '#9ca3af',
    textActive: isDark ? '#e0e0f0' : '#4338ca',
    bgActive: isDark ? 'rgba(99,102,241,0.12)' : '#eef2ff',
    borderActive: isDark ? 'rgba(99,102,241,0.3)' : '#c7d2fe',
    bgHover: isDark ? 'rgba(255,255,255,0.04)' : '#f9fafb',
    bgSearch: isDark ? 'rgba(255,255,255,0.04)' : '#f9fafb',
    bgTransparent: 'transparent',
    inputBg: isDark ? 'rgba(255,255,255,0.08)' : '#fff',
    border: isDark ? 'rgba(255,255,255,0.08)' : '#f0f1f5',
    dangerText: isDark ? '#f87171' : '#ef4444',
    primaryBtn: isDark ? '#6366f1' : undefined,
  };

  const list = tab === 'active' ? active : archived;

  // 防抖搜索
  useEffect(() => {
    const q = searchQ.trim();
    if (!q) {
      setSearchHits([]);
      setSearchSessionTitles([]);
      return;
    }
    const t = setTimeout(async () => {
      setSearching(true);
      try {
        const r = await SessionAPI.search(agentId, q, { includeArchived: true, limit: 30 });
        setSearchHits(r.messages || []);
        setSearchSessionTitles(r.sessions || []);
      } catch (e: any) {
        message.error('搜索失败：' + (e?.message ?? e));
      } finally {
        setSearching(false);
      }
    }, 250);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchQ]);

  const handleNew = async () => {
    const created = await SessionAPI.create(agentId);
    setActive((l) => [created, ...l]);
    setTab('active');
    onChange(created.id);
  };

  const handleDelete = async (id: string) => {
    await SessionAPI.remove(agentId, id);
    const nextActive = active.filter((s) => s.id !== id);
    const nextArchived = archived.filter((s) => s.id !== id);
    setActive(nextActive);
    setArchived(nextArchived);
    if (id === activeSessionId) {
      const fallback = nextActive[0] || nextArchived[0];
      if (fallback) onChange(fallback.id);
      else {
        const c = await SessionAPI.create(agentId);
        setActive([c]);
        onChange(c.id);
      }
    }
  };

  const handleArchive = async (s: ChatSession, archive: boolean) => {
    await SessionAPI.archive(agentId, s.id, archive);
    message.success(archive ? '已归档' : '已恢复');
    load();
  };

  const handleShare = async (s: ChatSession) => {
    try {
      const r = await SessionAPI.share(agentId, s.id, 0);
      const url = `${location.origin}/shared/${r.token}`;
      try {
        await navigator.clipboard.writeText(url);
        message.success('🔗 公开分享链接已复制到剪贴板');
      } catch {
        Modal.info({
          title: '公开分享链接',
          content: (
            <div>
              <p>任何人凭此链接都可只读访问该会话：</p>
              <Input.TextArea value={url} readOnly autoSize />
            </div>
          )
        });
      }
    } catch (e: any) {
      message.error('生成链接失败：' + (e?.message ?? e));
    }
  };

  const handleRename = async (id: string) => {
    if (!editingTitle.trim()) {
      setEditingId(null);
      return;
    }
    await SessionAPI.rename(agentId, id, editingTitle.trim());
    setActive((l) => l.map((s) => (s.id === id ? { ...s, title: editingTitle.trim() } : s)));
    setArchived((l) => l.map((s) => (s.id === id ? { ...s, title: editingTitle.trim() } : s)));
    setEditingId(null);
    message.success('已重命名');
  };

  // 渲染单个会话
  const renderSession = (s: ChatSession) => {
    const isActive = s.id === activeSessionId;
    const editing = editingId === s.id;
    return (
      <List.Item
        key={s.id}
        onClick={() => (editing ? null : onChange(s.id))}
        style={{
          cursor: 'pointer',
          padding: '8px 10px',
          background: isActive ? c.bgActive : c.bgTransparent,
          borderRadius: 6,
          border: isActive ? `1px solid ${c.borderActive}` : '1px solid transparent',
          marginBottom: 4
        }}
      >
        <div style={{ flex: 1, minWidth: 0 }}>
          {editing ? (
            <Input
              size="small"
              autoFocus
              value={editingTitle}
              onChange={(e) => setEditingTitle(e.target.value)}
              onPressEnter={() => handleRename(s.id)}
              onBlur={() => handleRename(s.id)}
            />
          ) : (
            <>
              <div
                style={{
                  fontSize: 13,
                  fontWeight: isActive ? 600 : 500,
                  color: isActive ? c.textActive : c.text,
                  overflow: 'hidden',
                  textOverflow: 'ellipsis',
                  whiteSpace: 'nowrap'
                }}
              >
                💬 {s.title}
              </div>
              <div
                style={{
                  fontSize: 11,
                  color: c.textDim,
                  overflow: 'hidden',
                  textOverflow: 'ellipsis',
                  whiteSpace: 'nowrap',
                  marginTop: 2
                }}
              >
                {s.lastPreview || '无消息'} · {dayjs(s.lastAt || s.updatedAt).format('MM-DD HH:mm')}
              </div>
            </>
          )}
        </div>
        {!editing && (
          <div style={{ display: 'flex', gap: 2, marginLeft: 6 }} onClick={(e) => e.stopPropagation()}>
            <Tooltip title="重命名">
              <Button
                type="text"
                size="small"
                onClick={() => {
                  setEditingId(s.id);
                  setEditingTitle(s.title);
                }}
              >
                ✏️
              </Button>
            </Tooltip>
            <Tooltip title={tab === 'active' ? '归档' : '恢复'}>
              <Button type="text" size="small" onClick={() => handleArchive(s, tab === 'active')}>
                {tab === 'active' ? '📦' : '↩️'}
              </Button>
            </Tooltip>
            <Dropdown
              trigger={['click']}
              menu={{
                items: [
                  { key: 'md', label: '⬇️ Markdown (.md)' },
                  { key: 'json', label: '⬇️ JSON (.json)' }
                ],
                onClick: ({ key }) => {
                  SessionAPI.exportSession(agentId, s.id, key as 'md' | 'json');
                  message.success('已开始下载');
                }
              }}
            >
              <Tooltip title="导出会话">
                <Button type="text" size="small">
                  ⬇️
                </Button>
              </Tooltip>
            </Dropdown>
            <Tooltip title="分享公开链接（任何人都可只读访问）">
              <Button type="text" size="small" onClick={() => handleShare(s)}>
                🔗
              </Button>
            </Tooltip>
            <Popconfirm title="删除此会话（不可恢复）？" onConfirm={() => handleDelete(s.id)} okText="删除" cancelText="取消">
              <Button type="text" size="small" danger>
                🗑
              </Button>
            </Popconfirm>
          </div>
        )}
      </List.Item>
    );
  };

  const inSearchMode = searchQ.trim().length > 0;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <Button type="primary" onClick={handleNew} style={{ marginBottom: 8, background: c.primaryBtn }} block>
        ➕ 新对话
      </Button>

      <Input.Search
        placeholder="搜索会话与消息…"
        allowClear
        value={searchQ}
        onChange={(e) => setSearchQ(e.target.value)}
        style={{ marginBottom: 8 }}
        styles={isDark ? { input: { background: c.inputBg, borderColor: c.border, color: c.text } } : undefined}
      />

      {inSearchMode ? (
        <div style={{ flex: 1, overflow: 'auto' }}>
          {searching ? (
            <div style={{ padding: 16, textAlign: 'center' }}>
              <Spin size="small" />
            </div>
          ) : searchHits.length === 0 && searchSessionTitles.length === 0 ? (
            <Empty description="无匹配结果" image={Empty.PRESENTED_IMAGE_SIMPLE} />
          ) : (
            <>
              {searchSessionTitles.length > 0 && (
                <div style={{ marginBottom: 8 }}>
                  <div style={{ fontSize: 11, color: c.textDim, padding: '4px 8px' }}>
                    📁 会话标题命中 ({searchSessionTitles.length})
                  </div>
                  {searchSessionTitles.map((s) => (
                    <div
                      key={s.id}
                      onClick={() => onChange(s.id)}
                      style={{
                        cursor: 'pointer',
                        padding: '6px 10px',
                        borderRadius: 6,
                        marginBottom: 2,
                        background: activeSessionId === s.id ? c.bgActive : c.bgSearch,
                        fontSize: 12,
                        color: c.text
                      }}
                    >
                      💬 {s.title}
                      {s.archived && <Tag style={{ marginLeft: 6 }}>归档</Tag>}
                    </div>
                  ))}
                </div>
              )}
              {searchHits.length > 0 && (
                <div>
                  <div style={{ fontSize: 11, color: c.textDim, padding: '4px 8px' }}>
                    🔎 消息内容命中 ({searchHits.length})
                  </div>
                  {searchHits.map((h) => (
                    <div
                      key={h.id}
                      onClick={() =>
                        onChange(h.sessionId, { highlightMessageId: h.id })
                      }
                      style={{
                        cursor: 'pointer',
                        padding: 8,
                        borderRadius: 6,
                        marginBottom: 4,
                        background: c.bgSearch,
                        borderLeft: `3px solid ${h.role === 'user' ? '#6366f1' : '#10b981'}`
                      }}
                    >
                      <div style={{ fontSize: 11, color: c.textDim, marginBottom: 2 }}>
                        {h.role === 'user' ? '我' : 'AI'} · {h.sessionTitle}
                        {h.sessionArchived && <Tag style={{ marginLeft: 4 }}>归档</Tag>}
                        <span style={{ marginLeft: 6 }}>{dayjs(h.createdAt).format('MM-DD HH:mm')}</span>
                      </div>
                      <div
                        style={{ fontSize: 12, color: c.text, lineHeight: 1.4 }}
                        dangerouslySetInnerHTML={{ __html: h.snippet }}
                      />
                    </div>
                  ))}
                </div>
              )}
            </>
          )}
        </div>
      ) : (
        <>
          <Segmented
            size="small"
            block
            value={tab}
            onChange={(v) => setTab(v as any)}
            options={[
              { value: 'active', label: `💬 活跃 (${active.length})` },
              { value: 'archived', label: `📦 归档 (${archived.length})` }
            ]}
            style={{ marginBottom: 8 }}
          />
          {list.length === 0 ? (
            <Empty description={tab === 'active' ? '无活跃会话' : '无归档会话'} image={Empty.PRESENTED_IMAGE_SIMPLE} />
          ) : (
            <List
              size="small"
              dataSource={list}
              style={{ flex: 1, overflow: 'auto' }}
              renderItem={renderSession}
            />
          )}
        </>
      )}

      {/* 顶部全局样式 mark 标签高亮 */}
      <style>{`
        mark {
          background: #fef3c7;
          color: #b45309;
          padding: 0 2px;
          border-radius: 2px;
        }
      `}</style>
    </div>
  );
}
