import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { RequirementStatus } from '@ftb/shared';
import { CreateRequirementDto } from './dto/create-requirement.dto';
import { UpdateRequirementDto } from './dto/update-requirement.dto';

const VALID_TRANSITIONS: Record<string, string[]> = {
  [RequirementStatus.DRAFT]: [RequirementStatus.REVIEWING],
  [RequirementStatus.REVIEWING]: [RequirementStatus.APPROVED, RequirementStatus.REJECTED],
  [RequirementStatus.APPROVED]: [RequirementStatus.DELIVERED],
  [RequirementStatus.REJECTED]: [RequirementStatus.DRAFT],
  [RequirementStatus.DELIVERED]: [],
};

function createFallbackRequirementCode() {
  return `REQ-${Date.now().toString(36).toUpperCase()}-${Math.random()
    .toString(36)
    .slice(2, 6)
    .toUpperCase()}`;
}

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

  create(productId: string, dto: CreateRequirementDto) {
    return this.prisma.requirement.create({
      data: {
        productId,
        code: dto.code?.trim() || createFallbackRequirementCode(),
        title: dto.title,
        description: dto.description || '',
        priority: dto.priority ?? 0,
        creatorId: dto.creatorId,
      },
    });
  }

  findAll(productId: string, status?: string) {
    return this.prisma.requirement.findMany({
      where: {
        productId,
        ...(status ? { status } : {}),
      },
      orderBy: { createdAt: 'desc' },
      include: { creator: { select: { id: true, name: true } } },
    });
  }

  async findOne(productId: string, id: string) {
    const req = await this.prisma.requirement.findFirst({
      where: { id, productId },
      include: { creator: { select: { id: true, name: true } } },
    });
    if (!req) throw new NotFoundException('需求不存在');
    return req;
  }

  async update(productId: string, id: string, dto: UpdateRequirementDto) {
    await this.findOne(productId, id);
    return this.prisma.requirement.update({
      where: { id_productId: { id, productId } },
      data: {
        ...(dto.code !== undefined && { code: dto.code }),
        ...(dto.title !== undefined && { title: dto.title }),
        ...(dto.description !== undefined && { description: dto.description }),
        ...(dto.priority !== undefined && { priority: dto.priority }),
      },
    });
  }

  async updateStatus(productId: string, id: string, newStatus: string) {
    const req = await this.findOne(productId, id);
    const allowed = VALID_TRANSITIONS[req.status] || [];
    if (!allowed.includes(newStatus)) {
      throw new BadRequestException(
        `无法从 "${req.status}" 转换到 "${newStatus}"`,
      );
    }
    return this.prisma.requirement.update({
      where: { id_productId: { id, productId } },
      data: { status: newStatus },
    });
  }

  async remove(productId: string, id: string) {
    await this.findOne(productId, id);
    return this.prisma.requirement.delete({ where: { id_productId: { id, productId } } });
  }
}
