/** Theme repository for cloud-agnostic datastore operations. */

import { getCollection } from '@/lib/datastore';
import { Theme, ThemeCreate, ThemeUpdate } from '@/types/theme';
import type { DocumentCollection } from '@bytelyst/datastore';

// Theme docs use id as partition key and don't have a productId field
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function collection(): DocumentCollection<any> {
  return getCollection('themes', '/id');
}

export class ThemeRepository {
  async create(theme: ThemeCreate): Promise<Theme> {
    const now = new Date().toISOString();
    const newTheme: Theme = {
      id: crypto.randomUUID(),
      name: theme.name,
      description: theme.description || null,
      ios: (theme.ios || {}) as Theme['ios'],
      android: (theme.android || {}) as Theme['android'],
      desktop: (theme.desktop || {}) as Theme['desktop'],
      is_active: theme.is_active || false,
      is_default: theme.is_default || false,
      version: '1.0',
      created_at: now,
      updated_at: now,
      created_by: theme.created_by || null,
      type: 'theme',
    };

    const resource = await collection().create(newTheme);
    return resource as Theme;
  }

  async getById(id: string): Promise<Theme | null> {
    return collection().findById(id, id);
  }

  async getActive(): Promise<Theme | null> {
    const results = await collection().rawQuery<Theme>(
      `SELECT * FROM c
       WHERE c.type = 'theme' AND c.is_active = true
       ORDER BY c.is_default DESC, c.created_at DESC
       OFFSET 0 LIMIT 1`
    );
    return results[0] || null;
  }

  async getAll(): Promise<Theme[]> {
    return collection().rawQuery<Theme>(
      "SELECT * FROM c WHERE c.type = 'theme' ORDER BY c.created_at DESC"
    );
  }

  async update(id: string, update: ThemeUpdate): Promise<Theme | null> {
    const theme = await this.getById(id);
    if (!theme) return null;

    const updatedTheme = {
      ...theme,
      ...update,
      updated_at: new Date().toISOString(),
    } as Theme;

    // If setting as active, deactivate others
    if (update.is_active) {
      await this.deactivateAllOthers(id);
    }

    const resource = await collection().update(id, id, updatedTheme);
    return resource as Theme;
  }

  async setActive(id: string): Promise<boolean> {
    const theme = await this.getById(id);
    if (!theme) return false;

    // Deactivate all others
    await this.deactivateAllOthers(id);

    // Activate this one
    await this.update(id, { is_active: true });
    return true;
  }

  async delete(id: string): Promise<boolean> {
    try {
      await collection().delete(id, id);
      return true;
    } catch {
      return false;
    }
  }

  private async deactivateAllOthers(excludeId: string): Promise<void> {
    const resources = await collection().rawQuery<Theme>(
      'SELECT * FROM c WHERE c.type = @type AND c.id != @excludeId AND c.is_active = true',
      { type: 'theme', excludeId }
    );

    for (const item of resources) {
      await collection().update(item.id, item.id, {
        is_active: false,
        updated_at: new Date().toISOString(),
      });
    }
  }
}
