// Custom theme persistence — store, load, validate, import/export

import { getSetting, setSetting } from '../adapters/settings-bridge';
import { handleError, handleInfraError } from '../utils/handle-error';
import { type ThemePalette, type ThemeId, getPalette, PALETTE_KEYS } from './themes';

export interface CustomTheme {
  id: string;
  label: string;
  baseTheme: ThemeId;
  isDark: boolean;
  palette: ThemePalette;
}

const STORAGE_KEY = 'custom_themes';
const HEX_RE = /^#[0-9a-fA-F]{6}$/;

// --- Persistence ---

export async function loadCustomThemes(): Promise<CustomTheme[]> {
  try {
    const raw = await getSetting(STORAGE_KEY);
    if (!raw) return [];
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed.filter(isValidCustomTheme) : [];
  } catch (e) {
    handleInfraError(e, 'customThemes.load');
    return [];
  }
}

export async function saveCustomThemes(themes: CustomTheme[]): Promise<void> {
  try {
    await setSetting(STORAGE_KEY, JSON.stringify(themes));
  } catch (e) {
    handleError(e, 'customThemes.save', 'save your custom themes');
  }
}

export async function deleteCustomTheme(themes: CustomTheme[], id: string): Promise<CustomTheme[]> {
  const updated = themes.filter(t => t.id !== id);
  await saveCustomThemes(updated);
  return updated;
}

// --- Create from base ---

export function createFromBase(name: string, baseTheme: ThemeId): CustomTheme {
  const base = getPalette(baseTheme);
  return {
    id: `custom:${Date.now()}`,
    label: name,
    baseTheme,
    isDark: baseTheme !== 'latte',
    palette: { ...base },
  };
}

// --- Validation ---

function isValidCustomTheme(obj: unknown): obj is CustomTheme {
  if (!obj || typeof obj !== 'object') return false;
  const t = obj as Record<string, unknown>;
  if (typeof t.id !== 'string' || typeof t.label !== 'string') return false;
  if (!t.palette || typeof t.palette !== 'object') return false;
  return isValidPalette(t.palette as Record<string, unknown>);
}

export function isValidPalette(p: Record<string, unknown>): boolean {
  return PALETTE_KEYS.every(k => typeof p[k] === 'string' && HEX_RE.test(p[k] as string));
}

// --- Import / Export ---

export function exportThemeJson(theme: CustomTheme): string {
  return JSON.stringify({
    name: theme.label,
    version: 1,
    isDark: theme.isDark,
    palette: theme.palette,
  }, null, 2);
}

export function importThemeJson(json: string): CustomTheme {
  const data = JSON.parse(json);
  if (!data || typeof data !== 'object') throw new Error('Invalid theme JSON');
  if (typeof data.name !== 'string' || !data.name.trim()) throw new Error('Missing theme name');
  if (!data.palette || !isValidPalette(data.palette)) {
    throw new Error('Invalid palette — must have all 26 color keys as #hex values');
  }
  return {
    id: `custom:${Date.now()}`,
    label: data.name.trim(),
    baseTheme: 'mocha',
    isDark: data.isDark !== false,
    palette: data.palette,
  };
}
