const BASE = 'https://aihorde.net/api/v2';

export interface WorkerData {
    id: string;
    name: string;
    models: string[];
    uptime: number;
    online: boolean;
    maintenance_mode: boolean;
    max_length: number;
    max_context_length: number;
    requests_fulfilled: number;
    performance: string;
    kudos_rewards: number;
    kudos_details: {
        generated: number;
        uptime: number;
    };
    threads: number;
    trusted: boolean;
    info: string | null;
}

export interface WorkerEdit {
    name: string;
    info: string;
    maintenance: boolean;
}

export interface UserData {
    username: string;
    kudos: number;
    worker_count: number;
    worker_ids?: string[];
    records: {
        contribution: { tokens: number };
        fulfillment: { text: number };
    };
}

export interface PerformanceData {
    text_worker_count: number;
    queued_text_requests: number;
    queued_tokens: number;
    past_minute_tokens: number;
}

export interface ModelData {
    name: string;
    count: number;
    queued: number;
    jobs: number;
    performance: number;
    eta: number;
    type: string;
}

export interface LeaderboardEntry {
    username: string;
    kudos: number;
    id?: number;
}

const headers = (apiKey?: string): HeadersInit =>
    apiKey ? { 'apikey': apiKey, 'Content-Type': 'application/json' } : { 'Content-Type': 'application/json' };

export const fetchUser = async (apiKey: string): Promise<UserData> => {
    const res = await fetch(`${BASE}/find_user`, { headers: headers(apiKey) });
    if (!res.ok) throw new Error(`Failed to fetch user: ${res.status}`);
    return res.json();
};

export const fetchWorkers = async (): Promise<WorkerData[]> => {
    const res = await fetch(`${BASE}/workers?type=text`);
    if (!res.ok) throw new Error(`Failed to fetch workers: ${res.status}`);
    return res.json();
};

export const fetchWorker = async (id: string, apiKey: string): Promise<WorkerData> => {
    const res = await fetch(`${BASE}/workers/${id}`, { headers: headers(apiKey) });
    if (!res.ok) throw new Error(`Failed to fetch worker: ${res.status}`);
    return res.json();
};

export const fetchPerformance = async (): Promise<PerformanceData> => {
    const res = await fetch(`${BASE}/status/performance`);
    if (!res.ok) throw new Error(`Failed to fetch performance: ${res.status}`);
    return res.json();
};

export const fetchModels = async (): Promise<ModelData[]> => {
    const res = await fetch(`${BASE}/status/models?type=text&model_state=all`);
    if (!res.ok) throw new Error(`Failed to fetch models: ${res.status}`);
    return res.json();
};

export const fetchLeaderboard = async (page: number): Promise<LeaderboardEntry[]> => {
    const res = await fetch(`${BASE}/users?page=${page}&sort=kudos`);
    if (!res.ok) throw new Error(`Failed to fetch leaderboard: ${res.status}`);
    return res.json();
};

export const updateWorker = async (
    id: string,
    apiKey: string,
    patch: { name?: string; info?: string; maintenance_mode?: boolean }
): Promise<WorkerEdit> => {
    const res = await fetch(`${BASE}/workers/${id}`, {
        method: 'PUT',
        headers: headers(apiKey),
        body: JSON.stringify(patch),
    });
    if (!res.ok) throw new Error(`Failed to update worker: ${res.status}`);
    return res.json();
};

export const deleteWorker = async (id: string, apiKey: string): Promise<void> => {
    const res = await fetch(`${BASE}/workers/${id}`, {
        method: 'DELETE',
        headers: headers(apiKey),
    });
    if (!res.ok) throw new Error(`Failed to delete worker: ${res.status}`);
};
