import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { TempTrainers } from './entities/temp_trainers.entity';
// import { TrainerSpecializations } from '../trainer_specializations/entities/trainer_specializations.entity';
import { UserEntity } from '../user/entities/user.entity';
import { Trainers } from '../trainers/entities/trainers.entity';
import { Skills } from '../skills/entities/skills.entity';

@Injectable()
export class TempTrainersService {
  constructor(
    @InjectRepository(TempTrainers)
    private readonly tempTrainersRepository: Repository<TempTrainers>,
    private readonly dataSource: DataSource,

    // @InjectRepository(TrainerSpecializations)
    // private readonly trainerSpecRepo: Repository<TrainerSpecializations>,

    @InjectRepository(Skills)
    private readonly skillsepo: Repository<Skills>,

    @InjectRepository(Trainers)
    private readonly trainersRepository: Repository<Trainers>,

    @InjectRepository(UserEntity)
    private readonly usersRepository: Repository<UserEntity>,
  ) {}

  /**
   * Save a new trainer application into temp_trainers
   */
  async createTrainerApplication(
    data: Partial<TempTrainers>,
  ): Promise<TempTrainers> {
    // console.log('=== Service Debug ===');
    // console.log('Data received in service:', data);
    // console.log('idProof value:', data.idProof);
    // console.log('idProof type:', typeof data.idProof);

    const trainer = this.tempTrainersRepository.create({
      fullName: data.fullName,
      email: data.email,
      phone: data.phone,
      trainerType: data.trainerType,
      specializationId: data.specializationId,
      experienceYears: data.experienceYears,
      certifications: data.certifications,
      availabilityType: data.availabilityType,
      trainerProfile: data.trainerProfile,
      idProof: data.idProof, // file path or URL
      status: 'pending', // default status
    });

    // console.log('Trainer entity created:', trainer);
    // console.log('idProof in entity:', trainer.idProof);

    const savedTrainer = await this.tempTrainersRepository.save(trainer);
    // console.log('Saved trainer:', savedTrainer);
    // console.log('idProof in saved trainer:', savedTrainer.idProof);
    return savedTrainer;
  }

  async getApplications(
    page = 1,
    limit = 10,
    status?: 'pending' | 'approved' | 'rejected',
  ) {
    const where = status ? { status } : {};
    const [applications, total] =
      await this.tempTrainersRepository.findAndCount({
        where,
        skip: (page - 1) * limit,
        take: limit,
        order: { createdAt: 'DESC' },
      });

    // Populate specialization details for each application
    const applicationsWithSpecialization = await Promise.all(
      applications.map(async (app) => {
        let specialization = null;
        if (app.specializationId) {
          specialization = await this.skillsepo.findOne({
            where: { id: app.specializationId },
            select: ['id', 'skill_name', 'skill_type'],
          });
        }
        return {
          ...app,
          specialization,
        };
      }),
    );

    return {
      applications: applicationsWithSpecialization,
      pagination: {
        total,
        totalPages: Math.ceil(total / limit),
        currentPage: page,
        limit,
      },
    };
  }

  /**
   * Approve a trainer application
   */
  async approveTrainer(id: number, remarks?: string) {
    const tempTrainer = await this.tempTrainersRepository.findOne({
      where: { id },
    });
    if (!tempTrainer)
      throw new NotFoundException('Trainer application not found');
    await this.dataSource.transaction(async (manager) => {
      // 1. Check if user already exists
      let user = await manager
        .createQueryBuilder(UserEntity, 'user')
        .where('user.email = :email', { email: tempTrainer.email })
        .getOne();

      // 2. If user doesn’t exist → insert
      if (!user) {
        const insertUser = await manager
          .createQueryBuilder()
          .insert()
          .into(UserEntity)
          .values({
            username: tempTrainer.email,
            email: tempTrainer.email,
            password: 'trainer@12345', // TODO: hash properly
            role: 'trainer',
            fullName: tempTrainer.fullName,
            phone: tempTrainer.phone,
          })
          .execute();

        const newUserId = insertUser.identifiers[0].id;

        user = await manager
          .createQueryBuilder(UserEntity, 'user')
          .where('user.id = :id', { id: newUserId })
          .getOne();
      }

      // 3. Insert trainer profile
      await manager
        .createQueryBuilder()
        .insert()
        .into(Trainers)
        .values({
          user_id: user.id,
          trainerType: tempTrainer.trainerType,
          specialization_id: tempTrainer.specializationId,
          experience_years: tempTrainer.experienceYears,
          certifications: tempTrainer.certifications,
          availabilityType: tempTrainer.availabilityType as
            | 'full-time'
            | 'part-time'
            | 'freelance'
            | 'online'
            | 'offline', // ✅ now correct
          trainer_profile: tempTrainer.trainerProfile,
          id_proof: tempTrainer.idProof,
        })
        .execute();

      // 4. Update temp_trainer status with remarks if provided
      await manager
        .createQueryBuilder()
        .update(TempTrainers)
        .set({
          status: 'approved',
          ...(remarks && { remarks }),
        })
        .where('id = :id', { id })
        .execute();
    });

    return { success: true, message: 'Trainer approved successfully' };
  }

  /**
   * Reject a trainer application
   */
  async rejectTrainer(id: number, remarks?: string) {
    await this.tempTrainersRepository.update(id, {
      status: 'rejected',
      ...(remarks && { remarks }),
    });
    return { success: true, message: 'Trainer rejected successfully' };
  }

  /**
   * Find application by ID
   */
  async findById(id: number): Promise<any> {
    const application = await this.tempTrainersRepository.findOne({
      where: { id },
    });

    if (!application) {
      return null;
    }

    // Populate specialization details
    let specialization = null;
    if (application.specializationId) {
      specialization = await this.skillsepo.findOne({
        where: { id: application.specializationId },
        select: ['id', 'skill_name', 'skill_type'],
      });
    }

    return {
      ...application,
      specialization,
    };
  }

  /**
   * Get all active specializations by type
   */
  async getSpecializationsByType(skill_type: 'tech' | 'nontech') {
    return this.skillsepo.find({
      select: ['id', 'skill_name'],
      where: { is_active: true, skill_type },
      order: { skill_name: 'ASC' },
    });
  }
}
