import {
  ConflictException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';
import { DEFAULT_BUSINESS_TYPES } from './business-types.defaults';
import { Prisma } from '@prisma/client';

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

  listPublic() {
    return this.prisma.businessType.findMany({
      where: { isActive: true },
      orderBy: { label: 'asc' },
      select: { id: true, label: true, imageUrl: true },
    });
  }

  listAll() {
    return this.prisma.businessType.findMany({
      orderBy: { createdAt: 'asc' },
      select: {
        id: true,
        label: true,
        imageUrl: true,
        isActive: true,
        createdAt: true,
        updatedAt: true,
      },
    });
  }

  async listAllPaged(args: {
    page: number;
    limit: number;
    q?: string;
    isActive?: string;
  }) {
    const page = Math.max(1, Math.floor(args.page || 1));
    const limit = Math.min(100, Math.max(1, Math.floor(args.limit || 20)));
    const skip = (page - 1) * limit;
    const q = String(args.q ?? '').trim();
    const isActiveRaw =
      args.isActive != null ? String(args.isActive).trim().toLowerCase() : '';

    let isActive: boolean | undefined;
    if (isActiveRaw === 'true') isActive = true;
    else if (isActiveRaw === 'false') isActive = false;

    const where: Prisma.BusinessTypeWhereInput = {};
    if (isActive !== undefined) where.isActive = isActive;
    if (q) {
      where.OR = [
        { id: { contains: q, mode: 'insensitive' } },
        { label: { contains: q, mode: 'insensitive' } },
      ];
    }

    const [total, items] = await this.prisma.$transaction([
      this.prisma.businessType.count({ where }),
      this.prisma.businessType.findMany({
        where,
        orderBy: { createdAt: 'asc' },
        skip,
        take: limit,
        select: {
          id: true,
          label: true,
          imageUrl: true,
          isActive: true,
          createdAt: true,
          updatedAt: true,
        },
      }),
    ]);

    return { page, limit, total, items };
  }

  async ensureDefaultsSeededIfEmpty() {
    const count = await this.prisma.businessType.count();
    if (count > 0) return { seeded: 0, alreadySeeded: true };
    const created = await this.prisma.businessType.createMany({
      data: DEFAULT_BUSINESS_TYPES.map((t) => ({
        label: t.label,
        imageUrl: t.imageUrl,
        isActive: true,
      })),
      skipDuplicates: true,
    });
    return { seeded: created.count, alreadySeeded: false };
  }

  async create(dto: { label: string; imageUrl?: string }) {
    const label = dto.label.trim();
    try {
      return await this.prisma.businessType.create({
        data: { label, imageUrl: dto.imageUrl?.trim() || null, isActive: true },
        select: {
          id: true,
          label: true,
          imageUrl: true,
          isActive: true,
          createdAt: true,
          updatedAt: true,
        },
      });
    } catch {
      throw new ConflictException('Business type already exists');
    }
  }

  async update(
    id: string,
    dto: { label?: string; imageUrl?: string; isActive?: boolean },
  ) {
    const existing = await this.prisma.businessType.findUnique({
      where: { id },
      select: { id: true },
    });
    if (!existing) throw new NotFoundException('Business type not found');
    try {
      return await this.prisma.businessType.update({
        where: { id },
        data: {
          ...(dto.label !== undefined ? { label: dto.label.trim() } : {}),
          ...(dto.imageUrl !== undefined
            ? { imageUrl: dto.imageUrl.trim() || null }
            : {}),
          ...(dto.isActive !== undefined ? { isActive: dto.isActive } : {}),
        },
        select: {
          id: true,
          label: true,
          imageUrl: true,
          isActive: true,
          createdAt: true,
          updatedAt: true,
        },
      });
    } catch {
      throw new ConflictException('Business type label already exists');
    }
  }

  async remove(id: string) {
    const existing = await this.prisma.businessType.findUnique({
      where: { id },
      select: { id: true },
    });
    if (!existing) throw new NotFoundException('Business type not found');
    await this.prisma.businessType.delete({ where: { id } });
    return { deleted: true };
  }
}
