import { ForbiddenException, Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { CreateReceiptAliasDto } from './dto/create-receipt-alias.dto';

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

  findAllForUser(userId: number, role: string) {
    const where = role === 'admin'
      ? undefined
      : {
          OR: [
            { ownerId: userId, isGlobal: false },
            { isGlobal: true },
          ],
        };

    return this.prisma.receiptAlias.findMany({
      where,
      include: { product: { select: { id: true, name: true, canonicalName: true } } },
      orderBy: { receiptName: 'asc' },
    });
  }

  async upsert(dto: CreateReceiptAliasDto, userId: number, role: string) {
    const normalized = dto.receiptName.toLowerCase().trim();
    const wantsGlobal = dto.isGlobal === true;

    if (wantsGlobal && role !== 'admin') {
      throw new ForbiddenException('Endast admin kan skapa globala alias');
    }

    return this.upsertAliasRecord(
      normalized,
      dto.productId,
      wantsGlobal ? null : userId,
      wantsGlobal,
    );
  }

  private async upsertAliasRecord(
    receiptName: string,
    productId: number,
    ownerId: number | null,
    isGlobal: boolean,
  ) {
    const existing = await this.prisma.receiptAlias.findFirst({
      where: isGlobal
        ? { receiptName, isGlobal: true }
        : { receiptName, ownerId, isGlobal: false },
    });

    if (existing) {
      return this.prisma.receiptAlias.update({
        where: { id: existing.id },
        data: { productId },
      });
    }

    return this.prisma.receiptAlias.create({
      data: { receiptName, productId, ownerId, isGlobal },
    });
  }

  async remove(id: number, userId: number, role: string) {
    const alias = await this.prisma.receiptAlias.findUnique({ where: { id } });
    if (!alias) {
      throw new NotFoundException(`Aliaspost med id ${id} hittades inte`);
    }

    const canDelete =
      role === 'admin' ||
      (alias.ownerId === userId && alias.isGlobal === false);

    if (!canDelete) {
      throw new ForbiddenException('Du har inte behörighet att ta bort aliaset');
    }

    return this.prisma.receiptAlias.delete({ where: { id } });
  }
}
