import { create } from 'zustand';
import { GatewayClient, ConnectionState, getGatewayClient } from '../lib/gateway-client';

interface GatewayLog {
  timestamp: number;
  level: string;
  message: string;
}

interface Clone {
  id: string;
  name: string;
  role?: string;
  nickname?: string;
  scenarios?: string[];
  model?: string;
  createdAt: string;
}

interface UsageStats {
  totalSessions: number;
  totalMessages: number;
  totalTokens: number;
  byModel: Record<string, { messages: number; inputTokens: number; outputTokens: number }>;
}

interface ChannelInfo {
  id: string;
  type: string;
  label: string;
  status: 'active' | 'inactive' | 'error';
  accounts?: number;
  error?: string;
}

interface ScheduledTask {
  id: string;
  name: string;
  schedule: string;
  status: 'active' | 'paused' | 'completed' | 'error';
  lastRun?: string;
  nextRun?: string;
  description?: string;
}

interface GatewayStore {
  // Connection state
  connectionState: ConnectionState;
  gatewayVersion: string | null;
  error: string | null;
  logs: GatewayLog[];

  // Data
  clones: Clone[];
  usageStats: UsageStats | null;
  pluginStatus: any[];
  channels: ChannelInfo[];
  scheduledTasks: ScheduledTask[];

  // Client reference
  client: GatewayClient;

  // Actions
  connect: (url?: string, token?: string) => Promise<void>;
  disconnect: () => void;
  sendMessage: (message: string, sessionKey?: string) => Promise<{ runId: string }>;
  loadClones: () => Promise<void>;
  createClone: (opts: { name: string; role?: string; scenarios?: string[] }) => Promise<void>;
  deleteClone: (id: string) => Promise<void>;
  loadUsageStats: () => Promise<void>;
  loadPluginStatus: () => Promise<void>;
  loadChannels: () => Promise<void>;
  loadScheduledTasks: () => Promise<void>;
  clearLogs: () => void;
}

export const useGatewayStore = create<GatewayStore>((set, get) => {
  const client = getGatewayClient();

  // Wire up state change callback
  client.onStateChange = (state) => {
    set({ connectionState: state });
  };

  client.onLog = (level, message) => {
    set((s) => ({
      logs: [...s.logs.slice(-99), { timestamp: Date.now(), level, message }],
    }));
  };

  return {
    connectionState: 'disconnected',
    gatewayVersion: null,
    error: null,
    logs: [],
    clones: [],
    usageStats: null,
    pluginStatus: [],
    channels: [],
    scheduledTasks: [],
    client,

    connect: async (url?: string, token?: string) => {
      try {
        set({ error: null });
        const c = url ? getGatewayClient({ url, token }) : get().client;
        await c.connect();

        // Fetch initial data after connection
        try {
          const health = await c.health();
          set({ gatewayVersion: health?.version });
        } catch { /* health may not return version */ }
      } catch (err: any) {
        set({ error: err.message });
        throw err;
      }
    },

    disconnect: () => {
      get().client.disconnect();
    },

    sendMessage: async (message: string, sessionKey?: string) => {
      const c = get().client;
      return c.chat(message, { sessionKey });
    },

    loadClones: async () => {
      try {
        const result = await get().client.listClones();
        set({ clones: result?.clones || [] });
      } catch { /* ignore if method not available */ }
    },

    createClone: async (opts) => {
      try {
        await get().client.createClone(opts);
        await get().loadClones();
      } catch (err: any) {
        set({ error: err.message });
      }
    },

    deleteClone: async (id: string) => {
      try {
        await get().client.deleteClone(id);
        await get().loadClones();
      } catch (err: any) {
        set({ error: err.message });
      }
    },

    loadUsageStats: async () => {
      try {
        const stats = await get().client.getUsageStats();
        set({ usageStats: stats });
      } catch { /* ignore */ }
    },

    loadPluginStatus: async () => {
      try {
        const result = await get().client.getPluginStatus();
        set({ pluginStatus: result?.plugins || [] });
      } catch { /* ignore */ }
    },

    loadChannels: async () => {
      const channels: { id: string; type: string; label: string; status: 'active' | 'inactive' | 'error'; accounts?: number; error?: string }[] = [];
      try {
        // Try listing channels from Gateway
        const result = await get().client.listChannels();
        if (result?.channels) {
          set({ channels: result.channels });
          return;
        }
      } catch { /* channels.list may not be available */ }

      // Fallback: probe known channels individually
      try {
        const feishu = await get().client.getFeishuStatus();
        channels.push({
          id: 'feishu',
          type: 'feishu',
          label: '飞书 (Feishu)',
          status: feishu?.configured ? 'active' : 'inactive',
          accounts: feishu?.accounts || 0,
        });
      } catch {
        channels.push({ id: 'feishu', type: 'feishu', label: '飞书 (Feishu)', status: 'inactive' });
      }

      // QQ channel (check if qqbot plugin is loaded)
      const plugins = get().pluginStatus;
      const qqPlugin = plugins.find((p: any) => (p.name || p.id || '').toLowerCase().includes('qqbot'));
      if (qqPlugin) {
        channels.push({
          id: 'qqbot',
          type: 'qqbot',
          label: 'QQ 机器人',
          status: qqPlugin.status === 'active' ? 'active' : 'inactive',
        });
      }

      set({ channels });
    },

    loadScheduledTasks: async () => {
      try {
        const result = await get().client.listScheduledTasks();
        set({ scheduledTasks: result?.tasks || [] });
      } catch { /* ignore if heartbeat.tasks not available */ }
    },

    clearLogs: () => set({ logs: [] }),
  };
});
