import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateTemplateDto } from './dto/create-template.dto';
import { UpdateTemplateDto } from './dto/update-template.dto';

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

  private serializeBigInt(data: any): any {
    return JSON.parse(
      JSON.stringify(data, (_, v) => (typeof v === 'bigint' ? Number(v) : v)),
    );
  }

  async findAll(userId: number, type?: string) {
    const where: any = { userId };

    if (type) {
      where.type = type;
    }

    const templates = await this.prisma.template.findMany({
      where,
      orderBy: { createdAt: 'desc' },
    });

    return this.serializeBigInt(templates);
  }

  async findOne(userId: number, id: number) {
    const template = await this.prisma.template.findFirst({
      where: { id, userId },
    });

    if (!template) {
      throw new NotFoundException(`Template with ID ${id} not found`);
    }

    return this.serializeBigInt(template);
  }

  async create(userId: number, dto: CreateTemplateDto) {
    // If isDefault is true, unset other defaults of the same type
    if (dto.isDefault) {
      await this.prisma.template.updateMany({
        where: { userId, type: dto.type, isDefault: true },
        data: { isDefault: false },
      });
    }

    const template = await this.prisma.template.create({
      data: {
        ...dto,
        userId,
      },
    });

    return this.serializeBigInt(template);
  }

  async update(userId: number, id: number, dto: UpdateTemplateDto) {
    const existing = await this.prisma.template.findFirst({
      where: { id, userId },
    });

    if (!existing) {
      throw new NotFoundException(`Template with ID ${id} not found`);
    }

    // If setting as default, unset other defaults of the same type
    if (dto.isDefault) {
      const type = dto.type || existing.type;
      await this.prisma.template.updateMany({
        where: { userId, type, isDefault: true, id: { not: id } },
        data: { isDefault: false },
      });
    }

    const updated = await this.prisma.template.update({
      where: { id },
      data: dto,
    });

    return this.serializeBigInt(updated);
  }

  async remove(userId: number, id: number) {
    const existing = await this.prisma.template.findFirst({
      where: { id, userId },
    });

    if (!existing) {
      throw new NotFoundException(`Template with ID ${id} not found`);
    }

    await this.prisma.template.delete({ where: { id } });

    return { message: `Template with ID ${id} has been deleted` };
  }
}
