/**
 * Theme REST endpoints.
 *
 * GET    /themes          — list all themes (admin only)
 * POST   /themes          — create a new theme (admin only)
 * GET    /themes/active   — get active theme (public, no auth)
 * GET    /themes/:id      — get theme by id (admin only)
 * PUT    /themes/:id      — update a theme (admin only)
 * DELETE /themes/:id      — delete a theme (admin only)
 * POST   /themes/:id/activate — set a theme as active (admin only)
 */

import type { FastifyInstance } from 'fastify';
import { BadRequestError, ForbiddenError, UnauthorizedError } from '../../lib/errors.js';
import {
  CreateThemeSchema,
  UpdateThemeSchema,
  type ThemeDoc,
  type PlatformTheme,
} from './types.js';
import * as repo from './repository.js';

const DEFAULT_THEME = {
  primary: '#4caf50',
  secondary: '#2e7d32',
  accent: '#66bb6a',
  background: '#ffffff',
  surface: '#f5f5f5',
  error: '#f44336',
  warning: '#ff9800',
  success: '#4caf50',
};

const DEFAULT_DESKTOP_THEME = {
  ...DEFAULT_THEME,
  idle: '#4caf50',
  listening: '#e94560',
  processing: '#f5a623',
  offline: '#9e9e9e',
};

export async function themeRoutes(app: FastifyInstance) {
  function requireAdmin(req: import('fastify').FastifyRequest): string {
    const role = req.jwtPayload?.role;
    if (!role || !['super_admin', 'admin'].includes(role)) {
      throw new ForbiddenError('Admin access required');
    }
    const productId = req.jwtPayload?.productId;
    if (!productId) throw new UnauthorizedError('Missing productId in token');
    return productId;
  }

  // List all themes (admin only)
  app.get('/themes', async req => {
    const productId = requireAdmin(req);
    return await repo.getAll(productId);
  });

  // Create a new theme (admin only)
  app.post('/themes', async (req, reply) => {
    const productId = requireAdmin(req);
    const parsed = CreateThemeSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }
    const { name, description, ios, android, desktop, is_active, is_default } = parsed.data;
    const now = new Date().toISOString();

    const theme: ThemeDoc = {
      id: crypto.randomUUID(),
      productId,
      name,
      description: description ?? null,
      ios: (ios || DEFAULT_THEME) as PlatformTheme,
      android: (android || DEFAULT_THEME) as PlatformTheme,
      desktop: (desktop || DEFAULT_DESKTOP_THEME) as PlatformTheme,
      is_active: is_active ?? false,
      is_default: is_default ?? false,
      version: '1.0',
      created_at: now,
      updated_at: now,
      created_by: req.jwtPayload?.sub ?? null,
      type: 'theme',
    };

    const created = await repo.create(theme);
    reply.code(201);
    return created;
  });

  // Get active theme (public — no auth required, used by mobile/desktop clients)
  app.get('/themes/active', async req => {
    // Accept productId from query param or JWT
    const productId = (req.query as { productId?: string }).productId ?? req.jwtPayload?.productId;
    if (!productId) throw new BadRequestError('productId query param is required');

    const theme = await repo.getActive(productId);
    if (theme) return theme;

    // Return default theme if none is active
    return {
      id: 'default',
      productId,
      name: 'Default Green',
      description: 'Default green theme',
      ios: DEFAULT_THEME,
      android: DEFAULT_THEME,
      desktop: DEFAULT_DESKTOP_THEME,
      is_active: true,
      is_default: true,
      version: '1.0',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
      created_by: null,
      type: 'theme',
    };
  });

  // Get theme by id (admin only)
  app.get('/themes/:id', async req => {
    requireAdmin(req);
    const { id } = req.params as { id: string };
    const theme = await repo.getById(id);
    if (!theme) throw new BadRequestError('Theme not found');
    return theme;
  });

  // Update a theme (admin only)
  app.put('/themes/:id', async req => {
    requireAdmin(req);
    const { id } = req.params as { id: string };
    const parsed = UpdateThemeSchema.safeParse(req.body);
    if (!parsed.success) {
      throw new BadRequestError(parsed.error.issues.map(i => i.message).join('; '));
    }

    // If setting as active, deactivate others
    if (parsed.data.is_active) {
      const productId = req.jwtPayload?.productId;
      if (productId) await repo.setActive(id, productId);
    }

    const updated = await repo.update(id, parsed.data);
    if (!updated) throw new BadRequestError('Theme not found');
    return updated;
  });

  // Delete a theme (admin only)
  app.delete('/themes/:id', async req => {
    requireAdmin(req);
    const { id } = req.params as { id: string };
    const success = await repo.remove(id);
    if (!success) throw new BadRequestError('Theme not found');
    return { success: true };
  });

  // Activate a theme (admin only)
  app.post('/themes/:id/activate', async req => {
    const productId = requireAdmin(req);
    const { id } = req.params as { id: string };
    const success = await repo.setActive(id, productId);
    if (!success) throw new BadRequestError('Theme not found');
    const theme = await repo.getById(id);
    return theme;
  });
}
