import { Injectable, Inject, NotFoundException } from '@nestjs/common';
import {
  IUserProfileRepository,
  USER_PROFILE_REPOSITORY,
} from '../../domain/repositories/user-profile.repository.interface';
import {
  UserProfileEntity,
  EducationLevel,
  ImmigrationType,
  PlannedTimeline,
  MaritalStatus,
  NetWorthRange,
  EducationRecord,
  WorkRecord,
  LanguageScore,
  FamilyMember,
} from '../../domain/entities/user-profile.entity';

@Injectable()
export class UserProfileService {
  constructor(
    @Inject(USER_PROFILE_REPOSITORY)
    private readonly profileRepo: IUserProfileRepository,
  ) {}

  async getOrCreateProfile(userId: string): Promise<UserProfileEntity> {
    const existing = await this.profileRepo.findByUserId(userId);
    if (existing) {
      return existing;
    }

    const profile = UserProfileEntity.create(userId);
    await this.profileRepo.save(profile);
    return profile;
  }

  async getProfile(userId: string): Promise<UserProfileEntity> {
    const profile = await this.profileRepo.findByUserId(userId);
    if (!profile) {
      throw new NotFoundException('Profile not found');
    }
    return profile;
  }

  async updateBasicInfo(
    userId: string,
    data: {
      fullName?: string;
      birthDate?: Date;
      nationality?: string;
      currentCountry?: string;
      currentCity?: string;
      maritalStatus?: MaritalStatus;
    },
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateBasicInfo(data);
    await this.profileRepo.update(profile);
    return profile;
  }

  async updateImmigrationIntent(
    userId: string,
    data: {
      targetCountries?: string[];
      immigrationTypes?: ImmigrationType[];
      plannedTimeline?: PlannedTimeline;
      primaryPurpose?: string;
    },
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateImmigrationIntent(data);
    await this.profileRepo.update(profile);
    return profile;
  }

  async updateEducation(
    userId: string,
    data: {
      highestEducation?: EducationLevel;
      educationRecords?: EducationRecord[];
    },
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateEducation(data);
    await this.profileRepo.update(profile);
    return profile;
  }

  async updateWorkExperience(
    userId: string,
    data: {
      currentOccupation?: string;
      totalWorkYears?: number;
      workRecords?: WorkRecord[];
    },
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateWorkExperience(data);
    await this.profileRepo.update(profile);
    return profile;
  }

  async updateLanguageScores(
    userId: string,
    scores: LanguageScore[],
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateLanguageScores(scores);
    await this.profileRepo.update(profile);
    return profile;
  }

  async updateFamilyMembers(
    userId: string,
    members: FamilyMember[],
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateFamilyMembers(members);
    await this.profileRepo.update(profile);
    return profile;
  }

  async updateFinancialInfo(
    userId: string,
    data: {
      netWorthRange?: NetWorthRange;
      hasBusinessExperience?: boolean;
      businessYears?: number;
    },
  ): Promise<UserProfileEntity> {
    const profile = await this.getOrCreateProfile(userId);
    profile.updateFinancialInfo(data);
    await this.profileRepo.update(profile);
    return profile;
  }

  // Admin methods
  async findByTargetCountry(
    countryCode: string,
    options?: { limit?: number; offset?: number },
  ): Promise<UserProfileEntity[]> {
    return this.profileRepo.findByTargetCountry(countryCode, options);
  }

  async getCompletionStats(): Promise<{ low: number; medium: number; high: number }> {
    return this.profileRepo.countByCompletionRange();
  }
}
