import React from 'react';
import {
  CheckSquareOutlined,
  MenuFoldOutlined,
  MenuUnfoldOutlined,
  PaperClipOutlined,
  PlusOutlined,
} from '@ant-design/icons';
import Attachments from '@ant-design/x/es/attachments';
import Conversations from '@ant-design/x/es/conversations';
import Sender from '@ant-design/x/es/sender';
import type { ConversationItemType } from '@ant-design/x';
import type { AttachmentsProps } from '@ant-design/x/es/attachments';
import { Button, Dropdown, Spin, Tooltip, Typography } from 'antd';
import type { MenuProps } from 'antd';
import type { AiSkill } from './types';

export interface AiChatSidebarProps {
  className?: string;
  conversationItems: ConversationItemType[];
  activeConversationKey?: string;
  selectionMode: boolean;
  selectedKeys: string[];
  loadingList: boolean;
  conversationCount: number;
  onActiveChange: (key: string) => void;
  menu?: MenuProps | ((item: ConversationItemType) => MenuProps);
  onStartNewConversation: () => void;
  onSelectAll: () => void;
  onInvertSelection: () => void;
  onDeleteSelected: () => void;
  onExitSelectionMode: () => void;
  onEnterSelectionMode: () => void;
}

export const AiChatSidebar: React.FC<AiChatSidebarProps> = ({
  className,
  conversationItems,
  activeConversationKey,
  selectionMode,
  selectedKeys,
  loadingList,
  conversationCount,
  onActiveChange,
  menu,
  onStartNewConversation,
  onSelectAll,
  onInvertSelection,
  onDeleteSelected,
  onExitSelectionMode,
  onEnterSelectionMode,
}) => {
  return (
    <aside className={className ?? 'ai-chat-sidebar'}>
      <Conversations
        items={conversationItems}
        activeKey={activeConversationKey}
        onActiveChange={onActiveChange}
        menu={selectionMode ? undefined : menu}
        creation={
          selectionMode
            ? undefined
            : { label: '新对话', icon: <PlusOutlined />, onClick: onStartNewConversation }
        }
      />
      {loadingList && <Spin className="ai-chat-sidebar__loading" />}
      {!loadingList && !selectionMode && conversationCount === 0 ? (
        <div className="ai-chat-sidebar__empty">
          <Typography.Text type="secondary">暂无会话</Typography.Text>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            点击「新对话」开始提问
          </Typography.Text>
        </div>
      ) : null}
      <div className="ai-chat-sidebar__footer">
        {selectionMode ? (
          <>
            <span className="ai-chat-sidebar__selected-count">{selectedKeys.length} 已选</span>
            <Button size="small" type="text" onClick={onSelectAll}>
              全选
            </Button>
            <Button size="small" type="text" onClick={onInvertSelection}>
              反选
            </Button>
            <Button
              size="small"
              type="text"
              danger
              disabled={selectedKeys.length === 0}
              onClick={onDeleteSelected}
            >
              删除
            </Button>
            <Button size="small" type="text" onClick={onExitSelectionMode}>
              取消
            </Button>
          </>
        ) : (
          <Button
            size="small"
            type="text"
            icon={<CheckSquareOutlined />}
            disabled={conversationCount === 0}
            onClick={onEnterSelectionMode}
          >
            管理
          </Button>
        )}
      </div>
    </aside>
  );
};

export interface AiChatComposerProps {
  conversationTitle: string;
  input: string;
  onChange: (value: string) => void;
  isRequesting: boolean;
  onSubmit: (value: string) => void;
  onCancel: () => void;
  uploadItems: AttachmentsProps['items'];
  onCustomUpload: AttachmentsProps['customRequest'];
  onRemoveAttachment: AttachmentsProps['onRemove'];
  deepThinking: boolean;
  onDeepThinkingChange: (value: boolean) => void;
  lockedSkill?: AiSkill;
  onClearSkill: () => void;
  onToggleSidebar: () => void;
  sidebarOpen: boolean;
  skillMenu: MenuProps;
}

export const AiChatComposer: React.FC<AiChatComposerProps> = ({
  conversationTitle,
  input,
  onChange,
  isRequesting,
  onSubmit,
  onCancel,
  uploadItems,
  onCustomUpload,
  onRemoveAttachment,
  deepThinking,
  onDeepThinkingChange,
  lockedSkill,
  onClearSkill,
  onToggleSidebar,
  sidebarOpen,
  skillMenu,
}) => {
  return (
    <>
      <div className="ai-chat-toolbar">
        <Tooltip title={sidebarOpen ? '收起会话' : '展开会话'}>
          <Button
            type="text"
            icon={sidebarOpen ? <MenuFoldOutlined /> : <MenuUnfoldOutlined />}
            onClick={onToggleSidebar}
          />
        </Tooltip>
        <Typography.Text ellipsis>{conversationTitle}</Typography.Text>
        <Dropdown menu={skillMenu} trigger={['click']}>
          <Button size="small">{lockedSkill?.name || '自动技能'}</Button>
        </Dropdown>
      </div>
      <div className="ai-chat-composer">
        <Sender
          value={input}
          onChange={onChange}
          loading={isRequesting}
          onSubmit={onSubmit}
          onCancel={onCancel}
          onKeyDown={(e) => {
            // 中文输入法合成中的回车（确认候选词）不应触发发送。
            // 浏览器在 compositionend 后仍会派发 Enter keydown，
            // 此时 Sender 内部的 composition 标记已失效，需用
            // KeyboardEvent.isComposing / keyCode 229 兜底。
            if (e.nativeEvent.isComposing || e.keyCode === 229) {
              return false;
            }
            return undefined;
          }}
          autoSize={{ minRows: 1, maxRows: 6 }}
          placeholder="询问学生、考勤、宿舍或账单数据"
          skill={
            lockedSkill
              ? {
                  title: lockedSkill.name,
                  value: lockedSkill.key,
                  closable: { onClose: onClearSkill },
                }
              : undefined
          }
          header={
            (uploadItems ?? []).length > 0 && (
              <div className="ai-chat-sender-header">
                <Attachments
                  items={uploadItems}
                  customRequest={onCustomUpload}
                  onRemove={onRemoveAttachment}
                  accept="image/jpeg,image/png,image/webp,application/pdf,.docx,.xlsx"
                  multiple
                />
              </div>
            )
          }
          footer={
            <div className="ai-chat-sender-footer">
              <Tooltip title="添加附件">
                <Attachments
                  items={[]}
                  customRequest={onCustomUpload}
                  onRemove={onRemoveAttachment}
                  accept="image/jpeg,image/png,image/webp,application/pdf,.docx,.xlsx"
                  multiple
                  placeholder={{
                    title: '添加附件',
                    description: '图片、PDF、Word、Excel，单个不超过 10MB',
                  }}
                >
                  <Button type="text" icon={<PaperClipOutlined />} aria-label="添加附件" />
                </Attachments>
              </Tooltip>
              <Sender.Switch
                checkedChildren="深度思考"
                unCheckedChildren="普通"
                value={deepThinking}
                onChange={onDeepThinkingChange}
                disabled={isRequesting}
              />
            </div>
          }
        />
        <Typography.Text type="secondary" className="ai-chat-disclaimer">
          AI 操作均在权限范围内执行，写操作需通过表单确认，重要信息请以系统记录为准
        </Typography.Text>
      </div>
    </>
  );
};
