import { Injectable, NotFoundException } from '@nestjs/common';
import { CrmPrismaService } from '../prisma/crm-prisma.service';
import { CreatePipelineDto } from './dto/create-pipeline.dto';
import { UpdatePipelineDto } from './dto/update-pipeline.dto';
import { UpdateStageDto } from './dto/update-stage.dto';

@Injectable()
export class PipelinesService {
  constructor(private readonly prisma: CrmPrismaService) {}

  async create(tenantId: string, userId: string, dto: CreatePipelineDto) {
    return this.prisma.pipeline.create({
      data: {
        tenantId,
        name: dto.name,
        isDefault: dto.isDefault ?? false,
        createdBy: userId,
        stages: dto.stages
          ? {
              create: dto.stages.map((stage, index) => ({
                name: stage.name,
                sortOrder: stage.sortOrder ?? index,
                color: stage.color ?? '#6B7280',
                probability: stage.probability ?? 0,
              })),
            }
          : undefined,
      },
      include: { stages: { orderBy: { sortOrder: 'asc' } } },
    });
  }

  async findAll(tenantId: string) {
    return this.prisma.pipeline.findMany({
      where: { tenantId, isActive: true },
      include: {
        stages: { orderBy: { sortOrder: 'asc' } },
        _count: { select: { deals: true } },
      },
      orderBy: { createdAt: 'asc' },
    });
  }

  async findOne(tenantId: string, id: string) {
    const pipeline = await this.prisma.pipeline.findFirst({
      where: { id, tenantId },
      include: {
        stages: { orderBy: { sortOrder: 'asc' } },
        _count: { select: { deals: true } },
      },
    });

    if (!pipeline) {
      throw new NotFoundException('Pipeline nicht gefunden');
    }

    return pipeline;
  }

  async update(
    tenantId: string,
    id: string,
    userId: string,
    dto: UpdatePipelineDto,
  ) {
    await this.findOne(tenantId, id);

    return this.prisma.pipeline.update({
      where: { id },
      data: {
        ...dto,
        updatedBy: userId,
      },
      include: { stages: { orderBy: { sortOrder: 'asc' } } },
    });
  }

  async remove(tenantId: string, id: string) {
    await this.findOne(tenantId, id);
    return this.prisma.pipeline.delete({ where: { id } });
  }

  // Pipeline-Stage Management
  async addStage(
    tenantId: string,
    pipelineId: string,
    name: string,
    sortOrder: number,
    color?: string,
    probability?: number,
  ) {
    await this.findOne(tenantId, pipelineId);

    return this.prisma.pipelineStage.create({
      data: {
        pipelineId,
        name,
        sortOrder,
        color: color ?? '#6B7280',
        probability: probability ?? 0,
      },
    });
  }

  async updateStage(
    tenantId: string,
    pipelineId: string,
    stageId: string,
    dto: UpdateStageDto,
  ) {
    await this.findOne(tenantId, pipelineId);

    const stage = await this.prisma.pipelineStage.findFirst({
      where: { id: stageId, pipelineId },
    });

    if (!stage) {
      throw new NotFoundException('Pipeline-Stufe nicht gefunden');
    }

    return this.prisma.pipelineStage.update({
      where: { id: stageId },
      data: {
        ...(dto.name !== undefined && { name: dto.name }),
        ...(dto.sortOrder !== undefined && { sortOrder: dto.sortOrder }),
        ...(dto.color !== undefined && { color: dto.color }),
        ...(dto.probability !== undefined && { probability: dto.probability }),
      },
    });
  }

  async removeStage(tenantId: string, pipelineId: string, stageId: string) {
    await this.findOne(tenantId, pipelineId);

    const stage = await this.prisma.pipelineStage.findFirst({
      where: { id: stageId, pipelineId },
    });

    if (!stage) {
      throw new NotFoundException('Pipeline-Stufe nicht gefunden');
    }

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