import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { UpdatePreferencesDto } from './dto/update-preferences.dto';
import { Prisma } from '@prisma/client';

@Injectable()
export class UserPreferencesService {
  constructor(private readonly prisma: PrismaService) {}

  /**
   * Get user preferences, create with defaults if not exists
   */
  async findByUserId(userId: string) {
    // First check if user exists
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
    });

    if (!user) {
      throw new NotFoundException(`User with ID ${userId} not found`);
    }

    // Get or create preferences
    let preferences = await this.prisma.userPreference.findUnique({
      where: { userId },
    });

    if (!preferences) {
      preferences = await this.prisma.userPreference.create({
        data: {
          userId,
          theme: 'system',
          language: 'de',
          dashboardLayout: this.getDefaultDashboardLayout(),
          notifications: this.getDefaultNotificationPreferences(),
        },
      });
    }

    return preferences;
  }

  /**
   * Update user preferences
   */
  async update(userId: string, updateDto: UpdatePreferencesDto) {
    // Ensure preferences exist first
    await this.findByUserId(userId);

    return this.prisma.userPreference.update({
      where: { userId },
      data: {
        ...(updateDto.theme && { theme: updateDto.theme }),
        ...(updateDto.language && { language: updateDto.language }),
        ...(updateDto.dashboardLayout && {
          dashboardLayout: updateDto.dashboardLayout as unknown as Prisma.JsonArray,
        }),
        ...(updateDto.notifications && {
          notifications: updateDto.notifications as unknown as Prisma.JsonObject,
        }),
      },
    });
  }

  /**
   * Update only dashboard layout
   */
  async updateDashboardLayout(userId: string, layout: unknown[]) {
    await this.findByUserId(userId);

    return this.prisma.userPreference.update({
      where: { userId },
      data: {
        dashboardLayout: layout as Prisma.JsonArray,
      },
    });
  }

  /**
   * Reset preferences to defaults
   */
  async resetToDefaults(userId: string) {
    await this.findByUserId(userId);

    return this.prisma.userPreference.update({
      where: { userId },
      data: {
        theme: 'system',
        language: 'de',
        dashboardLayout: this.getDefaultDashboardLayout(),
        notifications: this.getDefaultNotificationPreferences(),
      },
    });
  }

  /**
   * Default dashboard layout configuration
   */
  private getDefaultDashboardLayout(): Prisma.JsonArray {
    return [
      { id: 'stats-overview', type: 'statistics', x: 0, y: 0, w: 4, h: 1 },
      { id: 'recent-activity', type: 'activity', x: 0, y: 1, w: 2, h: 2 },
      { id: 'quick-actions', type: 'actions', x: 2, y: 1, w: 2, h: 2 },
      { id: 'upcoming-absences', type: 'absences', x: 0, y: 3, w: 2, h: 2 },
      { id: 'team-overview', type: 'team', x: 2, y: 3, w: 2, h: 2 },
    ];
  }

  /**
   * Default notification preferences
   */
  private getDefaultNotificationPreferences(): Prisma.JsonObject {
    return {
      email: true,
      push: true,
      absenceRequests: true,
      timeReminders: true,
      systemAnnouncements: true,
    };
  }
}
