import {
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreatePositionDto } from './dto/create-position.dto';
import { UpdatePositionDto } from './dto/update-position.dto';

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

  findAll(filters?: { countryId?: bigint; categoryId?: bigint }) {
    const where: { countryId?: bigint; categoryId?: bigint } = {};
    if (filters?.countryId !== undefined) where.countryId = filters.countryId;
    if (filters?.categoryId !== undefined) where.categoryId = filters.categoryId;
    return this.prisma.position.findMany({
      where,
      include: { country: true, category: true },
      orderBy: { indexVal: 'asc' },
    });
  }

  async findOne(id: bigint) {
    const p = await this.prisma.position.findUnique({
      where: { id },
      include: { country: true, category: true },
    });
    if (!p) throw new NotFoundException(`Position ${id} not found`);
    return p;
  }

  async create(dto: CreatePositionDto) {
    if (dto.countryId !== undefined) {
      await this.ensureCountry(dto.countryId);
    }
    if (dto.categoryId !== undefined) {
      await this.ensureCategory(dto.categoryId);
    }
    return this.prisma.position.create({
      data: {
        indexVal: dto.indexVal,
        countryId: dto.countryId === undefined ? null : BigInt(dto.countryId),
        categoryId: dto.categoryId === undefined ? null : BigInt(dto.categoryId),
      },
      include: { country: true, category: true },
    });
  }

  async update(id: bigint, dto: UpdatePositionDto) {
    await this.findOne(id);
    if (dto.countryId !== undefined && dto.countryId !== null) {
      await this.ensureCountry(dto.countryId);
    }
    if (dto.categoryId !== undefined && dto.categoryId !== null) {
      await this.ensureCategory(dto.categoryId);
    }
    return this.prisma.position.update({
      where: { id },
      data: {
        indexVal: dto.indexVal,
        country:
          dto.countryId === undefined
            ? undefined
            : dto.countryId === null
              ? { disconnect: true }
              : { connect: { id: BigInt(dto.countryId) } },
        category:
          dto.categoryId === undefined
            ? undefined
            : dto.categoryId === null
              ? { disconnect: true }
              : { connect: { id: BigInt(dto.categoryId) } },
      },
      include: { country: true, category: true },
    });
  }

  async remove(id: bigint) {
    await this.findOne(id);
    return this.prisma.position.delete({ where: { id } });
  }

  private async ensureCountry(id: number) {
    const c = await this.prisma.country.findUnique({ where: { id: BigInt(id) } });
    if (!c) throw new NotFoundException(`Country ${id} not found`);
  }

  private async ensureCategory(id: number) {
    const c = await this.prisma.category.findUnique({ where: { id: BigInt(id) } });
    if (!c) throw new NotFoundException(`Category ${id} not found`);
  }
}
