import { supabase } from './supabase.ts'

const DEVICE_ID_KEY = 'calctext-device-id'
const DEVICE_NAME_KEY = 'calctext-device-name'

/** Get or create a stable device fingerprint */
export function getDeviceId(): string {
  let id = localStorage.getItem(DEVICE_ID_KEY)
  if (!id) {
    id = crypto.randomUUID()
    localStorage.setItem(DEVICE_ID_KEY, id)
  }
  return id
}

/** Generate a human-readable device name from user agent */
export function getDeviceName(): string {
  const stored = localStorage.getItem(DEVICE_NAME_KEY)
  if (stored) return stored

  const ua = navigator.userAgent
  let name = 'Unknown Device'
  if (/Mac/.test(ua)) name = 'Mac'
  else if (/Windows/.test(ua)) name = 'Windows'
  else if (/Linux/.test(ua)) name = 'Linux'
  else if (/iPhone|iPad/.test(ua)) name = 'iOS'
  else if (/Android/.test(ua)) name = 'Android'

  const browser = /Chrome/.test(ua) ? 'Chrome'
    : /Firefox/.test(ua) ? 'Firefox'
    : /Safari/.test(ua) ? 'Safari'
    : /Edge/.test(ua) ? 'Edge'
    : ''

  if (browser) name += ` ${browser}`
  localStorage.setItem(DEVICE_NAME_KEY, name)
  return name
}

export interface DeviceSession {
  id: string
  user_id: string
  device_fingerprint: string
  device_name: string | null
  session_ttl_seconds: number
  last_password_auth_at: string
  created_at: string
}

/** Default TTL options in seconds */
export const TTL_OPTIONS = [
  { label: '1 hour', value: 3600 },
  { label: '1 day', value: 86400 },
  { label: '1 week', value: 604800 },
  { label: '30 days', value: 2592000 },
  { label: 'Never', value: 0 },
] as const

/**
 * Upsert the device session after successful password authentication.
 */
export async function recordPasswordAuth(userId: string): Promise<DeviceSession | null> {
  if (!supabase) return null

  const deviceId = getDeviceId()
  const deviceName = getDeviceName()

  const { data, error } = await supabase
    .from('device_sessions')
    .upsert(
      {
        user_id: userId,
        device_fingerprint: deviceId,
        device_name: deviceName,
        last_password_auth_at: new Date().toISOString(),
      },
      { onConflict: 'user_id,device_fingerprint' },
    )
    .select()
    .single()

  if (error) {
    console.error('Failed to record device session:', error)
    return null
  }
  return data
}

/**
 * Check if the current device session requires password re-entry.
 */
export async function checkPasswordRenewal(userId: string): Promise<boolean> {
  if (!supabase) return false

  const deviceId = getDeviceId()

  const { data, error } = await supabase
    .from('device_sessions')
    .select('session_ttl_seconds, last_password_auth_at')
    .eq('user_id', userId)
    .eq('device_fingerprint', deviceId)
    .single()

  if (error || !data) return false

  // TTL of 0 means "never expire"
  if (data.session_ttl_seconds === 0) return false

  const lastAuth = new Date(data.last_password_auth_at).getTime()
  const ttlMs = data.session_ttl_seconds * 1000
  return Date.now() - lastAuth > ttlMs
}

/**
 * Update the session TTL for the current device.
 */
export async function updateDeviceTTL(userId: string, ttlSeconds: number): Promise<void> {
  if (!supabase) return

  const deviceId = getDeviceId()

  await supabase
    .from('device_sessions')
    .update({ session_ttl_seconds: ttlSeconds })
    .eq('user_id', userId)
    .eq('device_fingerprint', deviceId)
}

/**
 * Get the current device session.
 */
export async function getDeviceSession(userId: string): Promise<DeviceSession | null> {
  if (!supabase) return null

  const deviceId = getDeviceId()

  const { data } = await supabase
    .from('device_sessions')
    .select('*')
    .eq('user_id', userId)
    .eq('device_fingerprint', deviceId)
    .single()

  return data
}
