import {
  Injectable,
  NotFoundException,
  ConflictException,
  BadRequestException,
} from '@nestjs/common';
import { CrmPrismaService } from '../prisma/crm-prisma.service';
import { CreateRelationshipDto } from './dto/create-relationship.dto';

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

  async create(
    tenantId: string,
    companyId: string,
    userId: string,
    dto: CreateRelationshipDto,
  ) {
    // Selbst-Referenz verhindern
    if (companyId === dto.relatedCompanyId) {
      throw new BadRequestException(
        'Ein Unternehmen kann keine Beziehung zu sich selbst haben',
      );
    }

    // Company validieren
    const company = await this.prisma.company.findFirst({
      where: { id: companyId, tenantId },
    });
    if (!company) {
      throw new NotFoundException('Unternehmen nicht gefunden');
    }

    // Related Company validieren
    const relatedCompany = await this.prisma.company.findFirst({
      where: { id: dto.relatedCompanyId, tenantId },
    });
    if (!relatedCompany) {
      throw new NotFoundException('Verknuepftes Unternehmen nicht gefunden');
    }

    // RelationshipType validieren
    const relType = await this.prisma.relationshipType.findFirst({
      where: { id: dto.relationshipTypeId, tenantId },
    });
    if (!relType) {
      throw new NotFoundException('Beziehungstyp nicht gefunden');
    }

    // Duplikat pruefen
    const existing = await this.prisma.companyRelationship.findUnique({
      where: {
        companyId_relatedCompanyId_relationshipTypeId: {
          companyId,
          relatedCompanyId: dto.relatedCompanyId,
          relationshipTypeId: dto.relationshipTypeId,
        },
      },
    });
    if (existing) {
      throw new ConflictException('Diese Beziehung existiert bereits');
    }

    return this.prisma.companyRelationship.create({
      data: {
        tenantId,
        companyId,
        relatedCompanyId: dto.relatedCompanyId,
        relationshipTypeId: dto.relationshipTypeId,
        notes: dto.notes,
        createdBy: userId,
      },
      include: {
        relatedCompany: {
          select: { id: true, name: true, industry: true, city: true },
        },
        relationshipType: {
          select: { id: true, name: true },
        },
      },
    });
  }

  async findByCompany(tenantId: string, companyId: string) {
    // Beziehungen in beide Richtungen laden
    const [outgoing, incoming] = await Promise.all([
      this.prisma.companyRelationship.findMany({
        where: { tenantId, companyId },
        include: {
          relatedCompany: {
            select: { id: true, name: true, industry: true, city: true },
          },
          relationshipType: {
            select: { id: true, name: true },
          },
        },
        orderBy: { createdAt: 'desc' },
      }),
      this.prisma.companyRelationship.findMany({
        where: { tenantId, relatedCompanyId: companyId },
        include: {
          company: {
            select: { id: true, name: true, industry: true, city: true },
          },
          relationshipType: {
            select: { id: true, name: true },
          },
        },
        orderBy: { createdAt: 'desc' },
      }),
    ]);

    // Eingehende Beziehungen umformatieren (damit relatedCompany immer die "andere" Seite ist)
    const normalizedIncoming = incoming.map((rel) => ({
      id: rel.id,
      tenantId: rel.tenantId,
      companyId: rel.relatedCompanyId,
      relatedCompanyId: rel.companyId,
      relationshipTypeId: rel.relationshipTypeId,
      notes: rel.notes,
      createdBy: rel.createdBy,
      createdAt: rel.createdAt,
      relatedCompany: rel.company,
      relationshipType: rel.relationshipType,
      direction: 'incoming' as const,
    }));

    const normalizedOutgoing = outgoing.map((rel) => ({
      ...rel,
      direction: 'outgoing' as const,
    }));

    return [...normalizedOutgoing, ...normalizedIncoming];
  }

  async remove(tenantId: string, companyId: string, relationshipId: string) {
    const rel = await this.prisma.companyRelationship.findFirst({
      where: {
        id: relationshipId,
        tenantId,
        OR: [{ companyId }, { relatedCompanyId: companyId }],
      },
    });

    if (!rel) {
      throw new NotFoundException('Beziehung nicht gefunden');
    }

    return this.prisma.companyRelationship.delete({
      where: { id: relationshipId },
    });
  }
}
