/**
 * Storage utilities for credentials and configuration
 */

import { encrypt, decrypt, generateEncryptionKey, exportKey, importKey, EncryptedData } from './crypto';

const STORAGE_KEYS = {
  ENCRYPTION_KEY: 'encryptionKey',
  CREDENTIALS: 'credentials',
  LAST_USE: 'lastCredentialUse'
};

export interface Credentials {
  username: string;
  password: string;
}

interface StoredCredentials {
  encrypted: EncryptedData;
  lastUse: number; // timestamp
}

/**
 * Initialize encryption key if not exists
 */
async function ensureEncryptionKey(): Promise<CryptoKey> {
  const stored = await chrome.storage.local.get(STORAGE_KEYS.ENCRYPTION_KEY);

  if (stored[STORAGE_KEYS.ENCRYPTION_KEY]) {
    return await importKey(stored[STORAGE_KEYS.ENCRYPTION_KEY]);
  }

  // Generate new key
  const key = await generateEncryptionKey();
  const exported = await exportKey(key);
  await chrome.storage.local.set({ [STORAGE_KEYS.ENCRYPTION_KEY]: exported });

  return key;
}

/**
 * Save credentials encrypted
 */
export async function saveCredentials(credentials: Credentials): Promise<void> {
  const key = await ensureEncryptionKey();
  const data = JSON.stringify(credentials);
  const encrypted = await encrypt(data, key);

  const storedData: StoredCredentials = {
    encrypted,
    lastUse: Date.now()
  };

  await chrome.storage.local.set({ [STORAGE_KEYS.CREDENTIALS]: storedData });
}

/**
 * Load and decrypt credentials
 * Returns null if no credentials stored or expired
 */
export async function loadCredentials(): Promise<Credentials | null> {
  const stored = await chrome.storage.local.get(STORAGE_KEYS.CREDENTIALS);
  const storedData: StoredCredentials | undefined = stored[STORAGE_KEYS.CREDENTIALS];

  if (!storedData) {
    return null;
  }

  // Check expiry (60 days = 60 * 24 * 60 * 60 * 1000 ms)
  const SIXTY_DAYS_MS = 60 * 24 * 60 * 60 * 1000;
  const now = Date.now();

  if (now - storedData.lastUse > SIXTY_DAYS_MS) {
    // Credentials expired, delete them
    await deleteCredentials();
    return null;
  }

  try {
    const key = await ensureEncryptionKey();
    const decrypted = await decrypt(storedData.encrypted, key);
    return JSON.parse(decrypted);
  } catch (error) {
    console.error('Failed to decrypt credentials:', error);
    // If decryption fails, delete corrupted data
    await deleteCredentials();
    return null;
  }
}

/**
 * Update last use timestamp
 */
export async function updateLastUse(): Promise<void> {
  const stored = await chrome.storage.local.get(STORAGE_KEYS.CREDENTIALS);
  const storedData: StoredCredentials | undefined = stored[STORAGE_KEYS.CREDENTIALS];

  if (storedData) {
    storedData.lastUse = Date.now();
    await chrome.storage.local.set({ [STORAGE_KEYS.CREDENTIALS]: storedData });
  }
}

/**
 * Delete stored credentials
 */
export async function deleteCredentials(): Promise<void> {
  await chrome.storage.local.remove(STORAGE_KEYS.CREDENTIALS);
}

/**
 * Check if credentials exist (without decrypting)
 */
export async function hasCredentials(): Promise<boolean> {
  const stored = await chrome.storage.local.get(STORAGE_KEYS.CREDENTIALS);
  return !!stored[STORAGE_KEYS.CREDENTIALS];
}
