import { defineStore } from 'pinia';
import { useUiStore } from './ui';

interface BackgroundCommand {
  command_id: string;
  status?: string;
  command?: string;
  notice_pending?: boolean;
  created_at?: number;
  updated_at?: number;
  finished_at?: number | null;
  timeout?: number;
  return_code?: number | null;
}

interface BackgroundCommandDetail extends BackgroundCommand {
  output?: string;
  message?: string;
}

interface BackgroundCommandState {
  commands: BackgroundCommand[];
  pollTimer: ReturnType<typeof setInterval> | null;
  detailPollTimer: ReturnType<typeof setInterval> | null;
  activeCommand: BackgroundCommand | null;
  stoppingCommandIds: Record<string, boolean>;
  activeDetail: BackgroundCommandDetail | null;
  detailLoading: boolean;
  detailError: string | null;
}

const TERMINAL_STATUSES = new Set(['completed', 'failed', 'timeout', 'cancelled']);

export const useBackgroundCommandStore = defineStore('backgroundCommand', {
  state: (): BackgroundCommandState => ({
    commands: [],
    pollTimer: null,
    detailPollTimer: null,
    activeCommand: null,
    stoppingCommandIds: {},
    activeDetail: null,
    detailLoading: false,
    detailError: null
  }),
  actions: {
    async fetchCommands() {
      try {
        const resp = await fetch('/api/background_commands?limit=200');
        if (!resp.ok) {
          throw new Error(await resp.text());
        }
        const data = await resp.json();
        if (data.success) {
          this.commands = Array.isArray(data.data) ? data.data : [];
          const activeId = this.activeCommand?.command_id;
          if (activeId) {
            const latest = this.commands.find((item) => item.command_id === activeId);
            if (latest) {
              this.activeCommand = { ...latest };
            }
          }
        }
      } catch (error) {
        console.error('获取后台指令列表失败:', error);
      }
    },
    startPolling() {
      if (this.pollTimer) {
        return;
      }
      const uiStore = useUiStore();
      this.pollTimer = setInterval(() => {
        if (uiStore.panelMode === 'backgroundCommands') {
          this.fetchCommands();
        }
      }, 5000);
    },
    stopPolling() {
      if (this.pollTimer) {
        clearInterval(this.pollTimer);
        this.pollTimer = null;
      }
    },
    openCommand(command: BackgroundCommand) {
      if (!command || !command.command_id) {
        return;
      }
      this.activeCommand = command;
      this.activeDetail = null;
      this.detailError = null;
      this.fetchCommandDetail(command.command_id);
      this.startDetailPolling();
    },
    closeCommand() {
      this.stopDetailPolling();
      this.activeCommand = null;
      this.activeDetail = null;
      this.detailError = null;
      this.detailLoading = false;
    },
    startDetailPolling() {
      if (this.detailPollTimer) {
        return;
      }
      this.detailPollTimer = setInterval(() => {
        const commandId = this.activeCommand?.command_id;
        if (commandId) {
          this.fetchCommandDetail(commandId);
        }
      }, 2000);
    },
    stopDetailPolling() {
      if (this.detailPollTimer) {
        clearInterval(this.detailPollTimer);
        this.detailPollTimer = null;
      }
    },
    async fetchCommandDetail(commandId: string) {
      if (!commandId) return;
      this.detailLoading = true;
      try {
        const resp = await fetch(`/api/background_commands/${encodeURIComponent(commandId)}`);
        if (!resp.ok) {
          throw new Error(await resp.text());
        }
        const data = await resp.json();
        if (data && data.success && data.data) {
          this.activeDetail = data.data;
          const current = this.commands.find((item) => item.command_id === commandId);
          if (current) {
            Object.assign(current, data.data);
          }
          if (this.activeCommand && this.activeCommand.command_id === commandId) {
            this.activeCommand = {
              ...this.activeCommand,
              ...data.data
            };
          }
          const status = (data.data.status || '').toString();
          if (TERMINAL_STATUSES.has(status)) {
            this.stopDetailPolling();
          }
        }
      } catch (error: any) {
        this.detailError = error?.message || String(error);
        console.error('获取后台指令详情失败:', error);
      } finally {
        this.detailLoading = false;
      }
    },
    async cancelCommand(commandId: string) {
      const normalizedId = (commandId || '').toString().trim();
      if (!normalizedId) {
        return { success: false, error: 'command_id 不能为空' };
      }
      this.stoppingCommandIds = {
        ...this.stoppingCommandIds,
        [normalizedId]: true
      };
      try {
        const resp = await fetch(
          `/api/background_commands/${encodeURIComponent(normalizedId)}/cancel`,
          { method: 'POST' }
        );
        const data = await resp.json().catch(() => ({}));
        if (!resp.ok || !data?.success) {
          throw new Error(data?.error || `HTTP ${resp.status}`);
        }
        await this.fetchCommands();
        if (this.activeCommand?.command_id === normalizedId) {
          await this.fetchCommandDetail(normalizedId);
        }
        return { success: true, data: data?.data || null };
      } catch (error: any) {
        const message = error?.message || String(error);
        return { success: false, error: message };
      } finally {
        const next = { ...this.stoppingCommandIds };
        delete next[normalizedId];
        this.stoppingCommandIds = next;
      }
    },
    async stopAllCommands(conversationId?: string): Promise<{ success: boolean; stoppedCount?: number; error?: string }> {
      try {
        const resp = await fetch('/api/background_commands/stop_all', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(conversationId ? { conversation_id: conversationId } : {})
        });
        const data = await resp.json().catch(() => ({}));
        if (!resp.ok || !data?.success) {
          throw new Error(data?.error || `HTTP ${resp.status}`);
        }
        await this.fetchCommands();
        return { success: true, stoppedCount: data?.data?.stopped_count || 0 };
      } catch (error: any) {
        return { success: false, error: error?.message || String(error) };
      }
    }
  }
});
