import axios from "axios";
import {
  registerWithFayda,
  type RegisterWithFaydaResponse,
} from "@/shared/services/authService";
import { getComplaintFaydaRedirectUri } from "@/shared/utils/faydaOidc";
import type { VerifiedCitizen } from "../types/complaint.types";

export class FaydaOidcError extends Error {
  constructor(
    readonly code: string,
    message?: string,
  ) {
    super(message ?? code);
    this.name = "FaydaOidcError";
  }
}

export interface FaydaRegistrationResult {
  registration: RegisterWithFaydaResponse;
  citizen?: VerifiedCitizen;
}

function mapRegisterWithFaydaError(error: unknown): never {
  if (axios.isAxiosError(error)) {
    const payload = error.response?.data;
    const serverCode =
      payload && typeof payload === "object" && "code" in payload
        ? String((payload as { code?: string }).code ?? "")
        : "";

    if (serverCode.startsWith("FAYDA_")) {
      throw new FaydaOidcError(serverCode);
    }

    if (!error.response) {
      throw new FaydaOidcError("FAYDA_TOKEN_NETWORK_ERROR");
    }

    const status = error.response.status;
    if (status === 400) {
      throw new FaydaOidcError("FAYDA_TOKEN_HTTP_400");
    }
    if (status === 401) {
      throw new FaydaOidcError("FAYDA_TOKEN_HTTP_401");
    }
    if (status >= 500) {
      throw new FaydaOidcError("FAYDA_TOKEN_HTTP_500");
    }
  }

  if (error instanceof FaydaOidcError) {
    throw error;
  }

  throw new FaydaOidcError("FAYDA_EXCHANGE_FAILED");
}

export async function registerFaydaCitizenFromCode(
  code: string,
  _preferredLocale = "en",
): Promise<FaydaRegistrationResult> {
  try {
    const response = await registerWithFayda({ code });
    const registration = response.data;

    if (!registration?.token?.trim()) {
      throw new FaydaOidcError("FAYDA_EXCHANGE_FAILED");
    }

    return { registration };
  } catch (error) {
    mapRegisterWithFaydaError(error);
  }
}
