import {
  deviceIdStorageKey,
  listOwnDevices,
  loadDevicePrivateKey,
  provisionNewDevice,
  touchDeviceLastSeen,
  type DeviceRecord,
} from '@chat-app/shared/auth';
import type { DevicePlatform } from '@chat-app/shared/supabase';

import { devLocalSecretStore } from './secretStore';
import { supabase } from './supabase';

export function detectDesktopPlatform(): DevicePlatform {
  const ua =
    typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string'
      ? navigator.userAgent.toLowerCase()
      : '';
  if (ua.includes('mac')) return 'macos';
  if (ua.includes('win')) return 'windows';
  return 'linux';
}

export function readLocalDeviceId(userId: string): string | null {
  return window.localStorage.getItem(deviceIdStorageKey(userId));
}

export function writeLocalDeviceId(userId: string, deviceId: string): void {
  window.localStorage.setItem(deviceIdStorageKey(userId), deviceId);
}

export function clearLocalDeviceId(userId: string): void {
  window.localStorage.removeItem(deviceIdStorageKey(userId));
}

// Look up the current install's device record. Returns null when either:
//   - no device id is cached locally, or
//   - the cached id was deleted server-side (e.g. wiped from Studio).
// In both cases the UI should prompt the user to register a fresh device.
export async function findExistingDevice(userId: string): Promise<DeviceRecord | null> {
  const cachedId = readLocalDeviceId(userId);
  if (!cachedId) return null;

  const all = await listOwnDevices(supabase);
  const hit = all.find((d) => d.id === cachedId) ?? null;
  if (!hit) return null;

  const priv = await loadDevicePrivateKey(devLocalSecretStore, userId, hit.id);
  if (!priv) {
    // Server row exists but we lost the private key locally — treat as fresh install.
    return null;
  }

  void touchDeviceLastSeen(supabase, hit.id).catch(() => {
    /* non-fatal */
  });
  return hit;
}

export async function registerCurrentDevice(params: {
  userId: string;
  name: string;
}): Promise<DeviceRecord> {
  const device = await provisionNewDevice({
    client: supabase,
    secretStore: devLocalSecretStore,
    userId: params.userId,
    name: params.name,
    platform: detectDesktopPlatform(),
  });
  writeLocalDeviceId(params.userId, device.id);
  return device;
}
