import { invoke } from "@tauri-apps/api/core";

export interface PlatformInfo {
  platform: "MacOS" | "Windows" | "Linux" | "Unknown";
  version: string;
  supports_ios_supervision: boolean;
}

export interface LocalServerInfo {
  url: string;
  qr_payload: string;
}

export interface SuperviseResult {
  success: boolean;
  stdout: string;
  stderr: string;
}

export interface RedeemPairingResponse {
  token: string;
  sessionId: string;
  createdAt: string;
}

export interface MagicSession {
  accessToken: string;
  sessionId: string;
  userId: string;
  createdAt: number;
  label: string | null;
}

export interface RegisterDeviceResponse {
  deviceId: string;
  dnsToken: string;
  profileUrl: string;
  existing: boolean;
}

export interface MagicDeviceInfo {
  source: string;
  deviceId: string;
  hardwareId: string | null;
  hostname: string;
  model: string | null;
  osVersion: string | null;
  mdmId: string | null;
  magicEnrolledAt: string | null;
  releaseRequestedAt: string | null;
  releaseAvailableAt: string | null;
  cooldownUntil: string | null;
  status: "active" | "cooldown" | "revoked" | "pending";
  lastSeenAt: string | null;
}

export interface ReleaseResponse {
  releaseRequestedAt: string;
  releaseAvailableAt: string;
}

export interface UserProfile {
  nickname: string | null;
  avatar: string | null;
  plan: string | null;
}

export interface IphoneDeviceState {
  udid: string;
  name: string;
  productType: string;
  productVersion: string;
  isSupervised: boolean;
  organizationName?: string;
  findMyEnabled?: boolean;
  installedProfileIDs: string[];
  installedAppBundleIDs: string[];
}

export interface DesktopProtectionState {
  active: boolean;
  platform: string;
  activatedAt: string;
}

export interface MdmStatusData {
  enrolled: boolean;
  company: string | null;
  supervised: boolean;
  lockProfileInstalled: boolean;
  lastAppPushAt: string | null;
}

export interface MdmStatusByUdidData {
  enrolled: boolean;
  company: string | null;
  supervised: boolean;
  lastAppPushAt: string | null;
}

export interface SuperviseStatus {
  isSupervised: boolean;
  organizationName?: string;
  findMyEnabled?: boolean;
}

export interface MdmPushStatus {
  udid: string;
  push_result: string;
}

export interface MdmCommandResult {
  command_uuid: string;
  response_body: string;
}

export const REBREAK_MDM_VERSION = "0.1";

export function getInstalledMdmVersion(installedProfileIDs: string[]): string | null {
  const versionId = installedProfileIDs.find((id) => id.startsWith("org.rebreak.mdm.version."));
  return versionId?.replace("org.rebreak.mdm.version.", "") ?? null;
}

async function invokeLogged<T>(command: string, args?: Record<string, unknown>): Promise<T> {
  const { useLogger } = await import("~/composables/useLogger");
  const logger = useLogger();

  try {
    logger.info(`invoke:${command}`, args ? JSON.stringify(args, null, 2) : undefined);
    const result = await invoke<T>(command, args);
    logger.debug(`invoke:${command}:ok`, typeof result === "object" ? JSON.stringify(result, null, 2) : String(result));
    return result;
  } catch (err) {
    const { formatError } = await import("~/composables/useLogger");
    const formatted = formatError(err);
    logger.error(`invoke:${command}:failed`, formatted.details ? `${formatted.message}\n${formatted.details}` : formatted.message);
    throw err;
  }
}

export function useTauri() {
  async function getPlatform(): Promise<PlatformInfo> {
    return await invokeLogged("get_platform");
  }

  async function redeemPairingCode(code: string, label?: string): Promise<RedeemPairingResponse> {
    return await invokeLogged("redeem_pairing_code", { code, label });
  }

  async function registerDevice(
    model?: string,
    osVersion?: string,
  ): Promise<RegisterDeviceResponse> {
    return await invokeLogged("register_device", { model, osVersion });
  }

  async function getHardwareId(): Promise<string> {
    return await invokeLogged("get_hardware_id");
  }

  async function getDeviceId(): Promise<string | null> {
    return await invokeLogged("get_device_id");
  }

  async function getStoredSession(): Promise<MagicSession | null> {
    return await invokeLogged("get_stored_session");
  }

  async function getMagicDevices(): Promise<MagicDeviceInfo[]> {
    return await invokeLogged("get_magic_devices");
  }

  async function getMagicStatus(dnsToken: string): Promise<boolean> {
    return await invokeLogged("get_magic_status", { dnsToken });
  }

  async function requestRelease(deviceId: string): Promise<ReleaseResponse> {
    return await invokeLogged("request_release", { deviceId });
  }

  async function cancelRelease(deviceId: string): Promise<void> {
    return await invokeLogged("cancel_release", { deviceId });
  }

  async function startCooldown(deviceId: string, durationMinutes: number = 60): Promise<{ cooldownUntil: string }> {
    return await invokeLogged("start_cooldown", { deviceId, durationMinutes });
  }

  async function cancelCooldown(deviceId: string): Promise<void> {
    await invokeLogged("cancel_cooldown", { deviceId });
  }

  async function logoutMagic(): Promise<void> {
    return await invokeLogged("logout_magic");
  }

  async function startLocalProfileServer(profilePath: string): Promise<LocalServerInfo> {
    return await invokeLogged("start_local_profile_server", { profilePath });
  }

  async function stopLocalProfileServer(): Promise<void> {
    await invokeLogged("stop_local_profile_server");
  }

  async function runSuperviseMagic(action: string, args?: string[]): Promise<SuperviseResult> {
    return await invokeLogged("run_supervise_magic", { action, args });
  }

  async function downloadProfile(profileUrl: string): Promise<string> {
    return await invokeLogged("download_profile", { profileUrl });
  }

  async function activateProtection(profilePath: string): Promise<void> {
    return await invokeLogged("activate_protection", { profilePath });
  }

  async function fetchMe(): Promise<UserProfile> {
    return await invokeLogged("fetch_me");
  }

  async function detectIphoneState(): Promise<IphoneDeviceState | null> {
    return await invokeLogged("detect_iphone_state");
  }

  async function getSuperviseStatus(): Promise<SuperviseStatus> {
    return await invokeLogged("get_supervise_status");
  }

  async function getInstalledProfiles(): Promise<string[]> {
    return await invokeLogged("get_installed_profiles");
  }

  async function getInstalledApps(): Promise<string[]> {
    return await invokeLogged("get_installed_apps");
  }

  async function installProfile(path: string): Promise<SuperviseResult> {
    return await invokeLogged("install_profile", { path });
  }

  async function downloadAndPatchEnrollmentProfile(url: string, udid: string): Promise<string> {
    return await invokeLogged("download_and_patch_enrollment_profile", { url, udid });
  }

  async function mdmPing(): Promise<string> {
    return await invokeLogged("mdm_ping");
  }

  async function mdmPush(udid: string): Promise<MdmPushStatus> {
    return await invokeLogged("mdm_push", { udid });
  }

  async function mdmInstallApp(udid: string): Promise<MdmCommandResult> {
    return await invokeLogged("mdm_install_app", { udid });
  }

  async function mdmSetSupervisedMode(udid: string): Promise<MdmCommandResult> {
    return await invokeLogged("mdm_set_supervised_mode", { udid });
  }

  async function mdmTakeManagement(udid: string): Promise<MdmCommandResult> {
    return await invokeLogged("mdm_take_management", { udid });
  }

  async function mdmInstallLockProfile(udid: string, profilePath: string): Promise<MdmCommandResult> {
    return await invokeLogged("mdm_install_lock_profile", { udid, profilePath });
  }

  async function getDesktopProtectionStatus(): Promise<DesktopProtectionState | null> {
    return await invokeLogged("get_desktop_protection_status");
  }

  async function setDesktopProtectionStatus(active: boolean, platform: string): Promise<void> {
    await invokeLogged("set_desktop_protection_status", { active, platform });
  }

  async function getHostname(): Promise<string> {
    return await invokeLogged("get_hostname");
  }

  async function getMdmStatus(deviceId: string): Promise<MdmStatusData> {
    return await invokeLogged("get_mdm_status", { deviceId });
  }

  async function getMdmStatusByUdid(udid: string): Promise<MdmStatusByUdidData> {
    return await invokeLogged("get_mdm_status_by_udid", { udid });
  }

  async function linkMdmDevice(deviceId: string, mdmId: string): Promise<void> {
    await invokeLogged("link_mdm_device", { deviceId, mdmId });
  }

  async function reportDeviceProtectionState(
    deviceId: string,
    platform: string,
    protectionType: string,
    active: boolean,
    reason?: string,
  ): Promise<void> {
    await invokeLogged("report_device_protection_state", {
      deviceId,
      platform,
      protectionType,
      active,
      reason,
    });
  }

  return {
    getPlatform,
    redeemPairingCode,
    registerDevice,
    getStoredSession,
    getMagicDevices,
    getMagicStatus,
    requestRelease,
    cancelRelease,
    startCooldown,
    cancelCooldown,
    logoutMagic,
    startLocalProfileServer,
    stopLocalProfileServer,
    runSuperviseMagic,
    downloadProfile,
    activateProtection,
    fetchMe,
    detectIphoneState,
    getSuperviseStatus,
    getInstalledProfiles,
    getInstalledApps,
    installProfile,
    downloadAndPatchEnrollmentProfile,
    mdmPing,
    mdmPush,
    mdmInstallApp,
    mdmSetSupervisedMode,
    mdmTakeManagement,
    mdmInstallLockProfile,
    getDesktopProtectionStatus,
    setDesktopProtectionStatus,
    getHostname,
    getHardwareId,
    getDeviceId,
    getMdmStatus,
    getMdmStatusByUdid,
    linkMdmDevice,
    reportDeviceProtectionState,
  };
}
