import fetch from 'node-fetch';
import { LogSystem } from '../../core/log';

export interface GroupDto {
    id: number;
    name: string;
    adminLevel: number;
    primary: boolean;
    sort_id: number;
}

export interface AccountDto {
    id: number;
    name: string;
    groups: GroupDto[];
}

export interface AuthenticationResultSuccess {
    result: 'success';
    token: string;
    account: AccountDto;
}

interface AuthenticationResultError {
    result: 'error';
    reason: string;
}

interface AuthenticationResultOtp {
    result: 'otp';
}

export type AuthenticationResult =
    | AuthenticationResultSuccess
    | AuthenticationResultError
    | AuthenticationResultOtp;

export class SWRPApiSystem {
    url = process.env.SWRP_API_SERVER;
    key = process.env.SWRP_API_SERVER_KEY;

    async validate(token: string): Promise<false | AccountDto> {
        try {
            const response = await fetch(`${this.url}/auth/?token=${encodeURIComponent(token)}`, {
                method: 'get',
                headers: { apikey: String(this.key) },
            });
            if (response.status !== 200) return false;
            return response.json() as Promise<AccountDto>;
        } catch {
            return false;
        }
    }

    async authenticate(
        name: string,
        password: string,
        remember: boolean,
        otp: string | null,
    ): Promise<AuthenticationResult> {
        try {
            const response = await fetch(`${this.url}/auth`, {
                method: 'post',
                headers: { 'Content-Type': 'application/json', apikey: String(this.key) },
                body: JSON.stringify({ name, password, remember, otp: otp ?? null }),
            });
            const json = await response.json() as any;
            if (response.status === 201) {
                if (json.result === 'needOTP') return { result: 'otp' };
                if (json.result === 'success') return json as AuthenticationResultSuccess;
                return { result: 'error', reason: 'Invalid 201 Object' };
            }
            return { result: 'error', reason: json.message ?? 'Unknown Error' };
        } catch (err: any) {
            LogSystem.Error('SWRP API', 'authenticate', err?.message ?? String(err), {});
            return { result: 'error', reason: 'Server Error' };
        }
    }

    async getPlayerPermissions(characterId: number): Promise<EntityPermission[] | false> {
        try {
            const response = await fetch(`${this.url}/permissions/character/${characterId}`, {
                method: 'get',
                headers: { apikey: String(this.key) },
            });
            if (response.status !== 200) return false;
            return response.json() as Promise<EntityPermission[]>;
        } catch {
            return false;
        }
    }

    async getAccountGroups(accountId: number): Promise<GroupDto[] | false> {
        try {
            const response = await fetch(`${this.url}/groups/${accountId}`, {
                method: 'get',
                headers: { apikey: String(this.key) },
            });
            if (response.status !== 200) return false;
            return response.json() as Promise<GroupDto[]>;
        } catch {
            return false;
        }
    }
}

export const swrpApiSystem = new SWRPApiSystem();
