import { useEffect, useState } from 'react';
import type { RawMessage } from '../../shared/chat-model';
import { extractText, isInternalMessage } from '../../shared/chat-model';
import { taskCenterList, type TaskCenterItem } from '../../constants/taskCenterList';
import {
  ChatComposer,
  ChatHistoryPanel,
  ChatMessageList,
  TaskBoard,
  type ChatHistoryBucket,
  type ChatMessageItem,
  type TaskItem,
  type TaskTabValue,
} from '../../components/chat';
import { IPC_EVENTS } from '../../lib/constants';
import { invokeIpc } from '../../lib/host-api';
import {
  channelStore,
  chatStore,
  getCompletedTasks,
  getPendingTasks,
  taskStore,
  useChannelStore,
  useChatStore,
  useTaskStore,
  type StagedAttachment,
} from '../../stores';
import { AddChannelDialog, TaskOperationDialog } from './components';

type SessionBucketKey = 'today' | 'yesterday' | 'withinWeek' | 'withinTwoWeeks' | 'withinMonth' | 'older';

const HISTORY_BUCKET_META: Array<{ key: SessionBucketKey; label: string }> = [
  { key: 'today', label: '今天' },
  { key: 'yesterday', label: '昨天' },
  { key: 'withinWeek', label: '近7天' },
  { key: 'withinTwoWeeks', label: '近14天' },
  { key: 'withinMonth', label: '近30天' },
  { key: 'older', label: '更早' },
];

function getMessageTime(timestamp?: number): string {
  if (!timestamp) return '--';
  const date = new Date(timestamp < 1e12 ? timestamp * 1000 : timestamp);
  return date.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
  });
}

function getHistoryBucket(activityMs: number, currentMs: number): SessionBucketKey {
  if (!activityMs || activityMs <= 0) return 'older';

  const now = new Date(currentMs);
  const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
  const startOfYesterday = startOfToday - 24 * 60 * 60 * 1000;

  if (activityMs >= startOfToday) return 'today';
  if (activityMs >= startOfYesterday) return 'yesterday';

  const daysAgo = (startOfToday - activityMs) / (24 * 60 * 60 * 1000);
  if (daysAgo <= 7) return 'withinWeek';
  if (daysAgo <= 14) return 'withinTwoWeeks';
  if (daysAgo <= 30) return 'withinMonth';
  return 'older';
}

function formatHistoryTime(activityMs: number, currentMs: number): string {
  if (!activityMs || activityMs <= 0) return '--';

  const date = new Date(activityMs);
  const current = new Date(currentMs);
  const sameDay = date.toDateString() === current.toDateString();
  if (sameDay) {
    return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
  }

  const yesterday = new Date(current);
  yesterday.setDate(current.getDate() - 1);
  if (date.toDateString() === yesterday.toDateString()) {
    return `昨天 ${date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}`;
  }

  return `${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
}

function getTaskDateLabel(createdAt?: string): string {
  if (!createdAt) return '执行时段';

  const current = new Date(createdAt);
  const today = new Date();
  const y = today.getFullYear();
  const m = today.getMonth();
  const d = today.getDate();

  const cy = current.getFullYear();
  const cm = current.getMonth();
  const cd = current.getDate();

  if (cy === y && cm === m && cd === d) return '今天';

  const yesterday = new Date(y, m, d - 1);
  if (cy === yesterday.getFullYear() && cm === yesterday.getMonth() && cd === yesterday.getDate()) {
    return '昨天';
  }

  return `${String(cm + 1).padStart(2, '0')}/${String(cd).padStart(2, '0')}`;
}

function getTaskRoomTypeLabel(task: { roomType: string; roomList: Array<{ id?: string; pmsName?: string }> }): string {
  const matchedRoom = Array.isArray(task.roomList)
    ? task.roomList.find((item) => item.id === task.roomType)
    : null;

  return matchedRoom?.pmsName || task.roomType;
}

function mapMessages(messages: RawMessage[], streamingMessage: RawMessage | null): ChatMessageItem[] {
  const visibleMessages = messages
    .filter((message) => !isInternalMessage(message))
    .filter((message) => {
      if (message.role === 'user' || message.role === 'assistant') return true;
      return Boolean(extractText(message).trim());
    })
    .map((message): ChatMessageItem => ({
      id: message.id || `msg-${message.timestamp || Math.random()}`,
      role: message.role === 'user' ? 'user' : 'assistant',
      name: message.role === 'user' ? '你' : 'YINIAN',
      time: getMessageTime(message.timestamp),
      content: extractText(message),
      attachments: message._attachedFiles,
      isError: Boolean(message.isError),
    }));

  if (streamingMessage && extractText(streamingMessage).trim()) {
    visibleMessages.push({
      id: streamingMessage.id || `stream-${Date.now()}`,
      role: 'assistant',
      name: 'YINIAN',
      time: getMessageTime(streamingMessage.timestamp),
      content: extractText(streamingMessage),
      attachments: streamingMessage._attachedFiles,
      isStreaming: true,
    });
  }

  return visibleMessages;
}

export default function HomePage() {
  const chat = useChatStore();
  const taskState = useTaskStore();
  const channelState = useChannelStore();
  const [inputMessage, setInputMessage] = useState('');
  const [attachments, setAttachments] = useState<StagedAttachment[]>([]);
  const [activeTaskTab, setActiveTaskTab] = useState<TaskTabValue>('pending');
  const [taskCenterNotice, setTaskCenterNotice] = useState<string | null>(null);
  const [taskDialogOpen, setTaskDialogOpen] = useState(false);
  const [addChannelDialogOpen, setAddChannelDialogOpen] = useState(false);

  useEffect(() => {
    void chatStore.init();
    void taskStore.init();
    void channelStore.init();
  }, []);

  const currentMs = Date.now();
  const historyBuckets: ChatHistoryBucket[] = HISTORY_BUCKET_META.map((bucket) => ({
    ...bucket,
    sessions: [],
  }));
  const bucketMap = new Map(historyBuckets.map((bucket) => [bucket.key, bucket]));

  for (const session of [...chat.sessions].sort((left, right) => {
    const leftTime = chat.sessionLastActivity[left.key] || left.updatedAt || 0;
    const rightTime = chat.sessionLastActivity[right.key] || right.updatedAt || 0;
    return rightTime - leftTime;
  })) {
    const activityMs = chat.sessionLastActivity[session.key] || session.updatedAt || 0;
    const bucketKey = getHistoryBucket(activityMs, currentMs);
    const targetBucket = bucketMap.get(bucketKey);
    if (!targetBucket) continue;

    targetBucket.sessions.push({
      conversationId: session.key,
      title: chat.sessionLabels[session.key] || session.displayName || session.key,
      updatedAt: formatHistoryTime(activityMs, currentMs),
    });
  }

  const pendingTasks = getPendingTasks(taskState.tasks);
  const completedTasks = getCompletedTasks(taskState.tasks);
  const pendingTaskItems: TaskItem[] = pendingTasks.flatMap((task) => task.subTasks.map((subTask) => ({
    id: subTask.id,
    removeTaskId: task.id,
    title: subTask.name,
    description: subTask.message || task.title,
    status: subTask.status,
    meta: task.title,
  })));
  const completedTaskItems: TaskItem[] = completedTasks.map((task) => ({
    id: task.id,
    title: task.title,
    description: `${task.operation === 'open' ? '开启' : '关闭'} ${getTaskRoomTypeLabel(task)}`,
    status: task.status,
    meta: `${task.dateRange[0]} ~ ${task.dateRange[1]}`,
  }));
  const currentTaskSource = activeTaskTab === 'pending' ? pendingTasks : completedTasks;
  const latestTask = currentTaskSource[0];

  const visibleMessages = mapMessages(chat.messages, chat.streamingMessage);

  async function handleSendMessage(): Promise<void> {
    const sent = await chatStore.sendMessage(inputMessage, attachments);
    if (sent) {
      setInputMessage('');
      setAttachments([]);
    }
  }

  async function handleAttach(files: File[]): Promise<void> {
    const stagedFiles = await chatStore.stageAttachmentFiles(files);
    setAttachments((currentAttachments) => [...currentAttachments, ...stagedFiles]);
  }

  async function handleTaskCenterItem(item: TaskCenterItem): Promise<void> {
    setTaskCenterNotice(null);

    if (item.type === 'channel') {
      if (!channelState.selectedChannels.length) {
        setTaskCenterNotice('请先在当前项目里配置“已选渠道”，再执行一键打开。');
        return;
      }

      try {
        await invokeIpc(IPC_EVENTS.OPEN_CHANNEL, channelState.selectedChannels);
        setTaskCenterNotice('已触发“打开渠道”操作。');
      } catch (error) {
        setTaskCenterNotice(error instanceof Error ? error.message : String(error));
      }
      return;
    }

    setTaskDialogOpen(true);
  }

  async function handleSaveChannels(items: typeof channelState.selectedChannels): Promise<void> {
    await channelStore.saveSelectedChannels(items);
    setTaskCenterNotice('已更新“打开渠道”配置。');
    setAddChannelDialogOpen(false);
  }

  async function handleCreateTask(options: Parameters<typeof taskStore.createAndExecuteTask>[0]): Promise<void> {
    const { task, result } = await taskStore.createAndExecuteTask(options);
    setTaskDialogOpen(false);

    if (result.success) {
      setTaskCenterNotice(`已创建任务“${task.title}”。`);
      return;
    }

    setTaskCenterNotice(result.error || `任务“${task.title}”创建后执行失败。`);
  }

  async function handleRetryTask(taskId: string): Promise<void> {
    const result = await taskStore.retryFailedSubTasks(taskId);
    if (result.success) {
      setTaskCenterNotice('已重新触发失败子任务。');
      return;
    }

    setTaskCenterNotice(result.error || '重试失败，请稍后再试。');
  }

  return (
    <section className="h-full w-full min-h-0">
      <div className="flex h-full w-full min-h-0 flex-col gap-2 md:flex-row">
        <ChatHistoryPanel
          buckets={historyBuckets}
          loading={!chat.initialized}
          selectedConversationId={chat.currentSessionKey}
          onNewChat={() => {
            void chatStore.newSession();
          }}
          onSelectConversation={(conversationId) => {
            chatStore.switchSession(conversationId);
          }}
          onRenameConversation={(conversationId) => {
            const currentLabel = chat.sessionLabels[conversationId]
              || chat.sessions.find((session) => session.key === conversationId)?.displayName
              || '';
            const nextLabel = window.prompt('重命名对话', currentLabel);
            if (nextLabel) {
              chatStore.renameSession(conversationId, nextLabel);
            }
          }}
          onDeleteConversation={(conversationId) => {
            const confirmed = window.confirm('确定删除该会话吗？删除后将无法恢复。');
            if (confirmed) {
              void chatStore.deleteSession(conversationId);
            }
          }}
        />

        <div className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-[20px] bg-white shadow-[0_10px_30px_rgba(15,23,42,0.08)] dark:bg-[#1b1b1d]">
          <div className="flex items-center justify-between border-b border-[#edf2f7] px-6 py-4 dark:border-[#2a2a2d]">
            <div>
              <h2 className="text-base font-semibold text-[#171717] dark:text-gray-100">智能对话</h2>
              <div className="mt-1 text-xs text-[#99A0AE] dark:text-gray-500">
                网关状态：{chat.gatewayStatus === 'connected' ? '已连接' : chat.gatewayStatus === 'reconnecting' ? '重连中' : '未连接'}
              </div>
            </div>
            <button
              type="button"
              className="rounded-full border border-[#E5E8EE] px-3 py-1.5 text-xs text-[#525866] transition-colors hover:border-[#2B7FFF] hover:text-[#2B7FFF] dark:border-[#2a2a2d] dark:text-gray-300"
              onClick={() => {
                void chatStore.loadSessions();
                void chatStore.loadHistory();
              }}
            >
              刷新会话
            </button>
          </div>

          <div className="flex min-h-0 flex-1 flex-col">
            <ChatMessageList loading={chat.loading} messages={visibleMessages} />
            <ChatComposer
              attachments={attachments}
              error={chat.error}
              isSending={chat.sending}
              value={inputMessage}
              onAttach={handleAttach}
              onChange={setInputMessage}
              onDismissError={() => chatStore.clearError()}
              onRemoveAttachment={(index) => {
                setAttachments((currentAttachments) => currentAttachments.filter((_, currentIndex) => currentIndex !== index));
              }}
              onSend={() => {
                void handleSendMessage();
              }}
              onStop={() => {
                void chatStore.abortRun();
              }}
            />
          </div>

          <div className="border-t border-[#edf2f7] dark:border-[#2a2a2d]">
            <div className="px-4 py-3">
              <div className="flex items-center justify-between pb-3">
                <h3 className="text-base font-semibold text-[#171717] dark:text-gray-100">任务中心</h3>
                <div className="text-xs text-[#99A0AE] dark:text-gray-500">沿用当前视觉与入口结构</div>
              </div>

              {taskCenterNotice ? (
                <div className="mb-3 rounded-[12px] border border-[#dfeaf6] bg-[#f8fbff] px-4 py-3 text-sm text-[#525866] dark:border-[#2a2a2d] dark:bg-[#232327] dark:text-gray-300">
                  {taskCenterNotice}
                </div>
              ) : null}

              <div className="grid grid-cols-2 gap-4 max-[800px]:grid-cols-1">
                {taskCenterList.map((item) => (
                  <button
                    key={item.id}
                    type="button"
                    className="relative flex items-start gap-3 rounded-[10px] border border-[#dfeaf6] bg-white p-3.5 text-left transition-colors hover:bg-[#F5F7FA] dark:border-[#2a2a2d] dark:bg-[#1f1f22] dark:hover:bg-[#2a2a2d]"
                    onClick={() => {
                      void handleTaskCenterItem(item);
                    }}
                  >
                    {item.type === 'channel' ? (
                      <span
                        role="button"
                        tabIndex={0}
                        className="absolute right-2 top-2 rounded-full p-1 text-[#99A0AE] transition-colors hover:text-[#525866] dark:hover:text-gray-200"
                        onClick={(event) => {
                          event.stopPropagation();
                          setTaskCenterNotice(null);
                          void channelStore.refreshAvailableChannels();
                          setAddChannelDialogOpen(true);
                        }}
                        onKeyDown={(event) => {
                          if (event.key === 'Enter' || event.key === ' ') {
                            event.preventDefault();
                            event.stopPropagation();
                            setTaskCenterNotice(null);
                            void channelStore.refreshAvailableChannels();
                            setAddChannelDialogOpen(true);
                          }
                        }}
                        aria-label="配置渠道"
                      >
                        <svg viewBox="0 0 24 24" className="h-4 w-4 fill-none stroke-current" strokeWidth="1.8">
                          <path
                            d="M12 3V6M12 18V21M4.93 4.93L7.05 7.05M16.95 16.95L19.07 19.07M3 12H6M18 12H21M4.93 19.07L7.05 16.95M16.95 7.05L19.07 4.93M15 12A3 3 0 1 1 9 12A3 3 0 0 1 15 12Z"
                            strokeLinecap="round"
                            strokeLinejoin="round"
                          />
                        </svg>
                      </span>
                    ) : null}
                    <div className="flex h-11 w-11 items-center justify-center rounded-lg border border-dashed border-[#9fc0e8] bg-[#EFF6FF] text-[23px] text-[#3b82f6] dark:border-gray-700 dark:bg-[#222225]">
                      {item.icon}
                    </div>
                    <div>
                      <div className="font-semibold text-[#171717] dark:text-gray-100">{item.title}</div>
                      <div className="mt-1.5 text-[13px] text-[#9aa5b1] dark:text-gray-400">{item.desc}</div>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          </div>
        </div>

        <TaskBoard
          activeTab={activeTaskTab}
          completedItems={completedTaskItems}
          currentDateLabel={latestTask ? getTaskDateLabel(latestTask.createdAt) : '执行时段'}
          currentTime={latestTask ? `${latestTask.dateRange[0]} ~ ${latestTask.dateRange[1]}` : '--'}
          pendingItems={pendingTaskItems}
          onRemoveTask={(taskId) => {
            taskStore.removeTask(taskId);
          }}
          onRetryTask={(taskId) => {
            void handleRetryTask(taskId);
          }}
          onTabChange={setActiveTaskTab}
        />
      </div>

      <TaskOperationDialog
        open={taskDialogOpen}
        onClose={() => setTaskDialogOpen(false)}
        onConfirm={handleCreateTask}
      />

      <AddChannelDialog
        open={addChannelDialogOpen}
        loading={channelState.loading}
        availableChannels={channelState.availableChannels}
        initialSelected={channelState.selectedChannels}
        onClose={() => setAddChannelDialogOpen(false)}
        onConfirm={handleSaveChannels}
      />
    </section>
  );
}
