import { create } from 'zustand';
import { api } from '../lib/api.ts';

export interface Bot {
  id: string;
  name: string;
  avatar: string | null;
  description: string;
  owner_id: string;
  created_at: string;
}

export interface SlashCommand {
  id: string;
  bot_id: string;
  server_id: string;
  name: string;
  description: string;
}

interface BotState {
  bots: Bot[];
  loading: boolean;
  error: string | null;

  fetchBots: () => Promise<void>;
  createBot: (name: string, description: string) => Promise<Bot & { token: string }>;
  updateBot: (id: string, data: { name?: string; description?: string; avatar?: string }) => Promise<Bot>;
  deleteBot: (id: string) => Promise<void>;
  addToServer: (botId: string, serverId: string) => Promise<void>;
  removeFromServer: (botId: string, serverId: string) => Promise<void>;
  regenerateToken: (id: string) => Promise<{ token: string }>;

  fetchCommands: (botId: string) => Promise<SlashCommand[]>;
  createCommand: (botId: string, serverId: string, name: string, description: string) => Promise<SlashCommand>;
  deleteCommand: (botId: string, commandId: string) => Promise<void>;
  fetchServerCommands: (serverId: string) => Promise<SlashCommand[]>;
}

export const useBotStore = create<BotState>((set) => ({
  bots: [],
  loading: false,
  error: null,

  fetchBots: async () => {
    set({ loading: true, error: null });
    try {
      const bots = await api.get<Bot[]>('/bots');
      set({ bots, loading: false });
    } catch (error) {
      set({
        loading: false,
        error: error instanceof Error ? error.message : 'Failed to fetch bots',
      });
    }
  },

  createBot: async (name, description) => {
    set({ loading: true, error: null });
    try {
      const result = await api.post<Bot & { token: string }>('/bots', { name, description });
      set((state) => ({
        bots: [...state.bots, result],
        loading: false,
      }));
      return result;
    } catch (error) {
      set({
        loading: false,
        error: error instanceof Error ? error.message : 'Failed to create bot',
      });
      throw error;
    }
  },

  updateBot: async (id, data) => {
    set({ loading: true, error: null });
    try {
      const bot = await api.patch<Bot>(`/bots/${id}`, data);
      set((state) => ({
        bots: state.bots.map((b) => (b.id === id ? bot : b)),
        loading: false,
      }));
      return bot;
    } catch (error) {
      set({
        loading: false,
        error: error instanceof Error ? error.message : 'Failed to update bot',
      });
      throw error;
    }
  },

  deleteBot: async (id) => {
    set({ loading: true, error: null });
    try {
      await api.delete(`/bots/${id}`);
      set((state) => ({
        bots: state.bots.filter((b) => b.id !== id),
        loading: false,
      }));
    } catch (error) {
      set({
        loading: false,
        error: error instanceof Error ? error.message : 'Failed to delete bot',
      });
      throw error;
    }
  },

  addToServer: async (botId, serverId) => {
    set({ error: null });
    try {
      await api.post(`/bots/${botId}/servers`, { server_id: serverId });
    } catch (error) {
      set({
        error: error instanceof Error ? error.message : 'Failed to add bot to server',
      });
      throw error;
    }
  },

  removeFromServer: async (botId, serverId) => {
    set({ error: null });
    try {
      await api.delete(`/bots/${botId}/servers/${serverId}`);
    } catch (error) {
      set({
        error: error instanceof Error ? error.message : 'Failed to remove bot from server',
      });
      throw error;
    }
  },

  regenerateToken: async (id) => {
    set({ loading: true, error: null });
    try {
      const result = await api.post<{ token: string }>(`/bots/${id}/regenerate-token`);
      set({ loading: false });
      return result;
    } catch (error) {
      set({
        loading: false,
        error: error instanceof Error ? error.message : 'Failed to regenerate token',
      });
      throw error;
    }
  },

  fetchCommands: async (botId) => {
    try {
      return await api.get<SlashCommand[]>(`/bots/${botId}/commands`);
    } catch (error) {
      set({
        error: error instanceof Error ? error.message : 'Failed to fetch commands',
      });
      return [];
    }
  },

  createCommand: async (botId, serverId, name, description) => {
    set({ error: null });
    try {
      const cmd = await api.post<SlashCommand>(`/bots/${botId}/commands`, {
        server_id: serverId,
        name,
        description,
      });
      return cmd;
    } catch (error) {
      set({
        error: error instanceof Error ? error.message : 'Failed to create command',
      });
      throw error;
    }
  },

  deleteCommand: async (botId, commandId) => {
    set({ error: null });
    try {
      await api.delete(`/bots/${botId}/commands/${commandId}`);
    } catch (error) {
      set({
        error: error instanceof Error ? error.message : 'Failed to delete command',
      });
      throw error;
    }
  },

  fetchServerCommands: async (serverId) => {
    try {
      return await api.get<SlashCommand[]>(`/servers/${serverId}/commands`);
    } catch (error) {
      set({
        error: error instanceof Error ? error.message : 'Failed to fetch server commands',
      });
      return [];
    }
  },
}));
