import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository, InjectDataSource } from '@nestjs/typeorm';
import { plainToInstance } from 'class-transformer';
import { Repository, DataSource } from 'typeorm';
import {
  AuditStageName,
  CompanyAuditStage,
} from './entities/company-audit-stage.entity';
import { CompanyAudit } from '../company-audits/entities/company-audit.entity';
import { User } from '../user/entities/user.entity';
import { CreateCompanyAuditStageDto } from './dto/create-company-audit-stage.dto';
import { UpdateCompanyAuditStageDto } from './dto/update-company-audit-stage.dto';
import { CompanyAuditStageDto } from './dto/company-audit-stage.dto';

@Injectable()
export class CompanyAuditStagesService {
  [x: string]: any;
  constructor(
    @InjectRepository(CompanyAuditStage, 'certification_db')
    private readonly stageRepository: Repository<CompanyAuditStage>,

    @InjectRepository(CompanyAudit, 'certification_db')
    private readonly auditRepository: Repository<CompanyAudit>,

    @InjectRepository(User, 'certification_db')
    private readonly userRepository: Repository<User>,

    @InjectDataSource('certification_db')
    private readonly dataSource: DataSource,
  ) {}

  async create(dto: CreateCompanyAuditStageDto): Promise<CompanyAuditStage> {
    return await this.dataSource.transaction(async (manager) => {
      const audit = await manager.findOne(CompanyAudit, {
        where: { id: dto.auditId },
      });
      if (!audit) throw new NotFoundException('Audit not found');

      const auditBy = await manager.findOne(User, {
        where: { id: dto.auditById },
      });
      if (!auditBy) throw new NotFoundException('AuditBy user not found');

      const createdBy = await manager.findOne(User, {
        where: { id: dto.createdById },
      });
      if (!createdBy) throw new NotFoundException('CreatedBy user not found');

      const stageData: Partial<CompanyAuditStage> = {
        audit,
        stageName: dto.stageName as AuditStageName,
        auditDate: dto.auditDate ? new Date(dto.auditDate) : undefined,
        auditBy,
        technicalExpert: dto.technicalExpert,
        anzicCode: dto.anzicCode,
        remarks: dto.remarks,
        createdBy,
      };

      const stage = manager.create(CompanyAuditStage, stageData);
      return await manager.save(stage);
    });
  }
  async findAllStages(): Promise<CompanyAuditStageDto[]> {
    const stages = await this.stageRepository.find({
      relations: ['audit', 'audit.company', 'audit.auditType','auditBy', 'createdBy'], 
      order: { auditDate: 'ASC' },
    });

    return plainToInstance(CompanyAuditStageDto, stages, {
      excludeExtraneousValues: true,
    });
  }

  // service
  async findAll(auditId: number): Promise<CompanyAuditStageDto[]> {
    const stages = await this.stageRepository.find({
      where: { audit: { id: auditId } },
      relations: ['audit', 'audit.company','audit.auditType', 'auditBy', 'createdBy'],
      order: { auditDate: 'ASC' },
    });

    return plainToInstance(CompanyAuditStageDto, stages, {
      excludeExtraneousValues: true,
    });
  }
// company-audit-stages.service.ts
async findByCompanyId(companyId: number) {
  return this.stageRepository.find({
    where: { audit: { company: { id: companyId } } },
    relations: ['audit', 'auditBy', 'createdBy'],
  });
}


  // --- Find single stage ---
  async findOne(id: number): Promise<CompanyAuditStageDto> {
    const stage = await this.stageRepository.findOne({
      where: { id },
      relations: ['audit', 'audit.company', 'auditBy', 'createdBy'], // 👈 ADD 'audit.company'
      order: { auditDate: 'ASC' },
    });
    if (!stage) throw new NotFoundException('Stage not found');

    return plainToInstance(CompanyAuditStageDto, stage, {
      excludeExtraneousValues: true,
    });
  }

  // --- Update Stage ---
  async update(
    id: number,
    dto: UpdateCompanyAuditStageDto,
  ): Promise<CompanyAuditStage> {
    return await this.dataSource.transaction(async (manager) => {
      const stage = await manager.findOne(CompanyAuditStage, { where: { id } });
      if (!stage) throw new NotFoundException('Stage not found');

      if (dto.stageName !== undefined) stage.stageName = dto.stageName;
      if (dto.auditDate !== undefined)
        stage.auditDate = new Date(dto.auditDate);

      if (dto.auditById !== undefined) {
        const auditBy = await manager.findOne(User, {
          where: { id: dto.auditById },
        });
        if (!auditBy) throw new NotFoundException('AuditBy user not found');
        stage.auditBy = auditBy;
      }
      if (dto.technicalExpert !== undefined)
        stage.technicalExpert = dto.technicalExpert;
      if (dto.anzicCode !== undefined) stage.anzicCode = dto.anzicCode;
      if (dto.remarks !== undefined) stage.remarks = dto.remarks;

      return await manager.save(stage);
    });
  }

  // --- Delete Stage ---
  async remove(id: number): Promise<CompanyAuditStage> {
    const stage = await this.stageRepository.findOne({ where: { id } });
    if (!stage) throw new NotFoundException('Stage not found');
    return this.stageRepository.remove(stage);
  }
}
