import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Param,
  Body,
  NotFoundException,
} from '@nestjs/common';
import { EscalationPolicyRepository } from '../../../infrastructure/repositories/escalation-policy.repository';
import { EscalationPolicy } from '../../../domain/entities/escalation-policy.entity';
import * as crypto from 'crypto';

@Controller('api/v1/comm/escalation-policies')
export class EscalationPolicyController {
  constructor(
    private readonly policyRepository: EscalationPolicyRepository,
  ) {}

  @Get()
  async listPolicies() {
    const policies = await this.policyRepository.findAll();
    return policies.map((p) => this.serialize(p));
  }

  @Get(':id')
  async getPolicy(@Param('id') id: string) {
    const policy = await this.policyRepository.findById(id);
    if (!policy) {
      throw new NotFoundException(`Escalation policy ${id} not found`);
    }
    return this.serialize(policy);
  }

  @Post()
  async createPolicy(@Body() body: any) {
    const policy = new EscalationPolicy();
    policy.id = crypto.randomUUID();
    policy.tenantId = body.tenantId;
    policy.name = body.name;
    policy.severity = body.severity ?? 'medium';
    policy.isDefault = body.isDefault ?? false;
    policy.steps = this.mapStepsToEntity(body.steps ?? []);
    const saved = await this.policyRepository.save(policy);
    return this.serialize(saved);
  }

  @Put(':id')
  async updatePolicy(@Param('id') id: string, @Body() body: any) {
    const policy = await this.policyRepository.findById(id);
    if (!policy) {
      throw new NotFoundException(`Escalation policy ${id} not found`);
    }
    if (body.name !== undefined) policy.name = body.name;
    if (body.severity !== undefined) policy.severity = body.severity;
    if (body.isDefault !== undefined) policy.isDefault = body.isDefault;
    if (body.steps !== undefined) policy.steps = this.mapStepsToEntity(body.steps);
    const saved = await this.policyRepository.save(policy);
    return this.serialize(saved);
  }

  @Delete(':id')
  async deletePolicy(@Param('id') id: string) {
    const policy = await this.policyRepository.findById(id);
    if (!policy) {
      throw new NotFoundException(`Escalation policy ${id} not found`);
    }
    await this.policyRepository.delete(id);
    return { success: true };
  }

  /**
   * Web admin sends steps as { stepNumber, channels: string[], delayMinutes, contactIds }
   * Entity stores steps as { delaySeconds, channel, contactIds }
   * Map between the two formats.
   */
  private mapStepsToEntity(
    steps: any[],
  ): Array<{ delaySeconds: number; channel: string; contactIds?: string[] }> {
    return steps.map((s) => ({
      delaySeconds: s.delaySeconds ?? (s.delayMinutes ? s.delayMinutes * 60 : 0),
      channel: s.channel ?? (s.channels?.[0] ?? 'push'),
      contactIds: s.contactIds,
    }));
  }

  /**
   * Serialize entity to web admin format with friendly aliases.
   */
  private serialize(policy: EscalationPolicy) {
    return {
      id: policy.id,
      name: policy.name,
      severity: policy.severity,
      isDefault: policy.isDefault,
      steps: (policy.steps ?? []).map((s, i) => ({
        stepNumber: i + 1,
        channels: [s.channel],
        delayMinutes: Math.round((s.delaySeconds ?? 0) / 60),
        delaySeconds: s.delaySeconds,
        contactIds: s.contactIds ?? [],
      })),
    };
  }
}
