import { Injectable } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { DevItemStatus, DevItemType, DevItemPriority } from '@prisma/client';

export interface DevItemQueryParams {
  page: number;
  pageSize: number;
  status?: DevItemStatus;
  itemType?: DevItemType;
  ownerId?: string;
  parentId?: string;
  priority?: DevItemPriority;
  keyword?: string;
}

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

  async findMany(params: DevItemQueryParams) {
    const { page, pageSize, status, itemType, ownerId, parentId, priority, keyword } = params;

    const where: any = {
      deletedAt: null,
      ...(status ? { status } : {}),
      ...(itemType ? { itemType } : {}),
      ...(ownerId ? { ownerId } : {}),
      ...(parentId ? { parentId } : {}),
      ...(priority ? { priority } : {}),
    };

    if (keyword) {
      where.OR = [
        { title: { contains: keyword, mode: 'insensitive' } },
        { description: { contains: keyword, mode: 'insensitive' } },
      ];
    }

    const [items, total] = await this.prisma.$transaction([
      this.prisma.devItem.findMany({
        where,
        orderBy: { createdAt: 'desc' },
        skip: (page - 1) * pageSize,
        take: pageSize,
      }),
      this.prisma.devItem.count({ where }),
    ]);

    return { items, total };
  }

  async findById(id: string) {
    return this.prisma.devItem.findFirst({
      where: { id, deletedAt: null },
    });
  }

  async findParentItem(id: string) {
    return this.prisma.devItem.findFirst({
      where: { id, deletedAt: null },
    });
  }

  async create(data: any) {
    return this.prisma.devItem.create({ data });
  }

  async createWithSequence(data: any, prefix: string) {
    return this.prisma.$transaction(async (tx) => {
      const sequence = await tx.devItemSequence.upsert({
        where: { prefix },
        create: { prefix, current: 1 },
        update: { current: { increment: 1 } },
        select: { current: true },
      });

      const code = `${prefix}-${String(sequence.current).padStart(4, '0')}`;
      return tx.devItem.create({ data: { ...data, code } });
    });
  }

  async update(id: string, data: any) {
    return this.prisma.devItem.update({
      where: { id },
      data,
    });
  }
}
