import { defineStore } from 'pinia';
import type { CardInstance, ChatMessage, TaskState } from '../api/types';
import { connectChatStream, type ParsedSseEvent } from '../api/sse';
import { fetchCard, submitCardAction } from '../api/client';

export type ContextPanelMode = 'idle' | 'loading' | 'task' | 'error' | 'completed';
export type ConnectionStatus = 'online' | 'disconnected';

export interface CardPreview {
  id: string;
  cardKey: string;
  title: string;
  subtitle: string;
}

const CARD_TITLE_MAP: Record<string, string> = {
  'department-selection': '科室推荐',
  'doctor-selection': '医生选择',
  'time-slot-selection': '就诊时间',
  'confirm-appointment': '确认预约',
  'payment-qrcode': '支付',
  'appointment-success': '挂号成功',
};

export const useTerminalStore = defineStore('terminal', {
  state: () => ({
    deviceId: 'EMOON-WEB-DEMO-001',
    deviceType: 'self_service_kiosk',
    conversationId: '' as string,
    currentTraceId: '' as string,
    messages: [] as ChatMessage[],
    streaming: false,
    task: null as TaskState | null,
    activeCard: null as CardInstance | null,
    cardHistory: [] as CardInstance[],
    viewingCardId: null as string | null,
    cardPreviews: [] as CardPreview[],
    errorMessage: '' as string,
    connectionStatus: 'online' as ConnectionStatus,
    inputText: '',
    pendingActionKey: '',
    demoMode: import.meta.env.VITE_DEMO_MODE === 'true',
    sending: false,
    selection: {} as Record<string, string>,
  }),
  getters: {
    contextPanelMode(state): ContextPanelMode {
      if (state.errorMessage) return 'error';
      if (state.sending && !state.activeCard && !state.viewingCardId) return 'loading';
      if (this.displayedCard?.cardKey === 'appointment-success') return 'completed';
      if (this.displayedCard) return 'task';
      return 'idle';
    },
    displayedCard(state): CardInstance | null {
      if (state.viewingCardId) {
        return state.cardHistory.find((c) => c.cardInstanceId === state.viewingCardId) ?? state.activeCard;
      }
      return state.activeCard;
    },
    isDemo(): boolean {
      return this.demoMode;
    },
  },
  actions: {
    addMessage(message: ChatMessage) {
      this.messages.push(message);
    },
    appendAssistantDelta(text: string) {
      const last = this.messages[this.messages.length - 1];
      if (last?.role === 'assistant' && last.streaming) {
        last.content += text;
        return;
      }
      this.messages.push({
        id: crypto.randomUUID(),
        role: 'assistant',
        content: text,
        streaming: true,
      });
    },
    completeAssistantMessage() {
      const last = this.messages[this.messages.length - 1];
      if (last?.role === 'assistant') last.streaming = false;
    },
    setTask(task: TaskState) {
      this.task = task;
    },
    setActiveCard(card: CardInstance) {
      this.activeCard = card;
      this.viewingCardId = null;
      this.cardHistory.push(card);
      this.errorMessage = '';
      // Push mini card preview for chat feed
      const cardKey = card.cardKey;
      const title = CARD_TITLE_MAP[cardKey] || cardKey;
      const data = card.cardData || {};
      let subtitle = '';
      if (cardKey === 'department-selection') {
        const depts = data.departments as Array<{ name: string }> | undefined;
        subtitle = depts?.[0]?.name ? `${depts[0].name}${depts.length > 1 ? '等' + depts.length + '个科室' : ''}` : '';
      } else if (cardKey === 'doctor-selection') {
        const docs = data.doctors as Array<{ doctorName: string }> | undefined;
        subtitle = docs?.[0]?.doctorName || '';
      } else if (cardKey === 'time-slot-selection') {
        const slots = data.slots as Array<{ timePeriod: string }> | undefined;
        subtitle = slots?.[0]?.timePeriod || '';
      } else if (cardKey === 'confirm-appointment') {
        subtitle = '请确认预约信息';
      } else if (cardKey === 'payment-qrcode') {
        const amount = data.amountYuan || '0.00';
        subtitle = `Mock支付 ¥${amount}`;
      } else if (cardKey === 'appointment-success') {
        subtitle = '预约已确认';
      }
      this.cardPreviews.push({ id: card.cardInstanceId, cardKey, title, subtitle });
    },
    setError(message: string, traceId = '') {
      this.errorMessage = message;
      this.currentTraceId = traceId;
    },
    viewCard(cardInstanceId: string | null) {
      this.viewingCardId = cardInstanceId;
    },
    resetToIdle() {
      this.task = null;
      this.activeCard = null;
      this.viewingCardId = null;
      this.cardHistory = [];
      this.cardPreviews = [];
      this.errorMessage = '';
      this.pendingActionKey = '';
      this.selection = {};
    },

    saveSelection(payload: Record<string, unknown>) {
      for (const [key, value] of Object.entries(payload)) {
        if (typeof value === 'string') {
          this.selection[key] = value;
        }
      }
    },

    handleSseEvent(event: ParsedSseEvent) {
      switch (event.type) {
        case 'task_updated': {
          const data = event.data as unknown as TaskState;
          this.setTask(data);
          break;
        }
        case 'message_delta': {
          const text = event.data.text as string;
          if (text) this.appendAssistantDelta(text);
          this.streaming = true;
          break;
        }
        case 'message_completed': {
          this.completeAssistantMessage();
          this.streaming = false;
          if (event.data.conversationId) {
            this.conversationId = event.data.conversationId as string;
          }
          break;
        }
        case 'card_created': {
          const cardInstanceId = event.data.cardInstanceId as string;
          if (cardInstanceId) {
            fetchCard(cardInstanceId)
              .then((card) => this.setActiveCard(card))
              .catch((err) => this.setError(err.message));
          }
          break;
        }
        case 'error': {
          this.setError(
            (event.data.message as string) ?? '未知错误',
            (event.data.traceId as string) ?? '',
          );
          this.streaming = false;
          break;
        }
        case 'completed': {
          this.streaming = false;
          break;
        }
      }
    },

    async sendMessage(text: string): Promise<void> {
      if (this.sending) return; // 防重入：正在发送中不允许重复调用
      this.addMessage({ id: crypto.randomUUID(), role: 'user', content: text });
      this.errorMessage = '';
      this.sending = true;
      this.streaming = true;

      return new Promise((resolve, reject) => {
        connectChatStream({
          deviceId: this.deviceId,
          deviceType: this.deviceType,
          text,
          conversationId: this.conversationId || undefined,
          onEvent: (event) => this.handleSseEvent(event),
          onError: (error) => {
            this.setError(error.message);
            this.streaming = false;
            this.sending = false;
            reject(error);
          },
          onComplete: () => {
            this.streaming = false;
            this.sending = false;
            resolve();
          },
        });
      });
    },

    async submitCard(payload: Record<string, unknown>): Promise<void> {
      if (!this.activeCard) return;

      const actionName = this.activeCard.actions[0]?.actionName;
      if (!actionName) return;

      this.pendingActionKey = `${this.activeCard.cardInstanceId}-${actionName}`;
      this.errorMessage = '';

      try {
        const result = await submitCardAction(
          this.activeCard.cardInstanceId,
          actionName,
          payload,
        );

        if (result.nextCard?.cardInstanceId) {
          const fullCard = await fetchCard(result.nextCard.cardInstanceId);
          this.setActiveCard(fullCard);
        }
      } catch (err) {
        this.setError((err as Error).message);
        throw err;
      }
    },
  },
});
