import { useCallback, useEffect, useState } from "react";
import { get, post, put } from "./api";

export interface LevelingConfig {
  base: number;
  exponent: number;
  chat: {
    cooldownMs: number;
    minXp: number;
    maxXp: number;
  };
}

export interface EconomyConfig {
  daily: {
    amount: string;
    streakBonus: string;
    weeklyBonus: string;
    cooldownMs: number;
  };
  transfers: {
    allowSelfTransfer: boolean;
    minAmount: string;
  };
  exam: {
    multMin: number;
    multMax: number;
  };
}

export interface InventoryConfig {
  maxStackSize: string;
  maxSlots: number;
}

export interface LootdropConfig {
  activityWindowMs: number;
  minMessages: number;
  spawnChance: number;
  cooldownMs: number;
  reward: {
    min: number;
    max: number;
    currency: string;
  };
}

export interface TriviaConfig {
  entryFee: string;
  rewardMultiplier: number;
  timeoutSeconds: number;
  cooldownMs: number;
  categories: number[];
  difficulty: string;
}

export interface ModerationConfig {
  prune: {
    maxAmount: number;
    confirmThreshold: number;
    batchSize: number;
    batchDelayMs: number;
  };
}

export interface QuestConfig {
  maxActiveQuests: number;
}

export interface GameSettings {
  leveling: LevelingConfig;
  economy: EconomyConfig;
  inventory: InventoryConfig;
  lootdrop: LootdropConfig;
  trivia: TriviaConfig;
  moderation: ModerationConfig;
  quest: QuestConfig;
  commands: Record<string, boolean>;
  system: Record<string, unknown>;
}

export interface GuildSettings {
  guildId: string;
  configured: boolean;
  studentRoleId?: string;
  visitorRoleId?: string;
  colorRoleIds?: string[];
  welcomeChannelId?: string;
  welcomeMessage?: string;
  feedbackChannelId?: string;
  terminalChannelId?: string;
  terminalMessageId?: string;
  moderationLogChannelId?: string;
  moderationDmOnWarn?: boolean;
  moderationAutoTimeoutThreshold?: number;
  featureOverrides?: Record<string, boolean>;
}

export interface SettingsMeta {
  guildId?: string;
  roles: Array<{ id: string; name: string; color: string }>;
  channels: Array<{ id: string; name: string; type: number }>;
  commands: Array<{ name: string; category: string }>;
}

export function useSettings() {
  const [settings, setSettings] = useState<GameSettings | null>(null);
  const [guildSettings, setGuildSettings] = useState<GuildSettings | null>(null);
  const [meta, setMeta] = useState<SettingsMeta | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchSettings = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const [settingsData, metaData] = await Promise.all([
        get<GameSettings>("/api/settings"),
        get<SettingsMeta>("/api/settings/meta"),
      ]);
      setSettings(settingsData);
      setMeta(metaData);

      // Fetch guild settings if we have a guild ID
      if (metaData.guildId) {
        const gs = await get<GuildSettings>(
          `/api/guilds/${metaData.guildId}/settings`
        );
        setGuildSettings(gs);
      }
    } catch (e) {
      setError(e instanceof Error ? e.message : "Failed to load settings");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchSettings();
  }, [fetchSettings]);

  const saveSettings = useCallback(
    async (partial: Record<string, unknown>) => {
      try {
        setSaving(true);
        setError(null);
        await post("/api/settings", partial);
        const updated = await get<GameSettings>("/api/settings");
        setSettings(updated);
        return true;
      } catch (e) {
        setError(e instanceof Error ? e.message : "Failed to save settings");
        return false;
      } finally {
        setSaving(false);
      }
    },
    []
  );

  const saveGuildSettings = useCallback(
    async (data: Partial<GuildSettings>) => {
      if (!meta?.guildId) return false;
      try {
        setSaving(true);
        setError(null);
        await put(`/api/guilds/${meta.guildId}/settings`, data);
        const updated = await get<GuildSettings>(
          `/api/guilds/${meta.guildId}/settings`
        );
        setGuildSettings(updated);
        return true;
      } catch (e) {
        setError(
          e instanceof Error ? e.message : "Failed to save guild settings"
        );
        return false;
      } finally {
        setSaving(false);
      }
    },
    [meta?.guildId]
  );

  return {
    settings,
    guildSettings,
    meta,
    loading,
    saving,
    error,
    saveSettings,
    saveGuildSettings,
    refetch: fetchSettings,
  };
}
