import { Injectable, NotFoundException, InternalServerErrorException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ClientPricing } from './entities/client-pricing.entity';
import { ClientPricingTier } from './entities/client-pricing-tier.entity';
import { CreateClientPricingDto } from './dto/create-client-pricing.dto';
import { UpdateClientPricingDto } from './dto/update-client-pricing.dto';

@Injectable()
export class ClientPricingService {
  constructor(
    @InjectRepository(ClientPricing)
    private pricingRepo: Repository<ClientPricing>,
    @InjectRepository(ClientPricingTier)
    private tierRepo: Repository<ClientPricingTier>,
  ) {}

  async create(createDto: CreateClientPricingDto): Promise<ClientPricing> {
    try {
      const pricing = this.pricingRepo.create({
        title: createDto.title,
        subtitle: createDto.subtitle,
        mainFeatures: createDto.mainFeatures,
        icon: createDto.icon,
      });
      await this.pricingRepo.save(pricing);

      pricing.tiers = createDto.tiers.map(tierDto =>
        this.tierRepo.create({
          ...tierDto,
          pricing,
        }),
      );

      await this.tierRepo.save(pricing.tiers);

      return this.findOne(pricing.id);
    } catch (error) {
      console.error('Failed to create client pricing:', error);
      throw new InternalServerErrorException('Failed to create client pricing');
    }
  }

  async findAll(): Promise<ClientPricing[]> {
    try {
      return await this.pricingRepo.find({ relations: ['tiers'] });
    } catch (error) {
      console.log('Err is', error);

      throw new InternalServerErrorException('Failed to fetch client pricing list');
    }
  }

  async findOne(id: number): Promise<ClientPricing> {
    try {
      const pricing = await this.pricingRepo.findOne({
        where: { id },
        relations: ['tiers'],
      });
      if (!pricing) throw new NotFoundException(`Pricing with id ${id} not found`);
      return pricing;
    } catch (error) {
      if (error instanceof NotFoundException) throw error;
      throw new InternalServerErrorException('Failed to fetch client pricing');
    }
  }

  async update(id: number, updateDto: UpdateClientPricingDto): Promise<ClientPricing> {
    try {
      const pricing = await this.findOne(id);

      await this.tierRepo.delete({ pricing: { id } });

      pricing.title = updateDto.title ?? pricing.title;
      pricing.subtitle = updateDto.subtitle ?? pricing.subtitle;
      pricing.mainFeatures = updateDto.mainFeatures ?? pricing.mainFeatures;
      pricing.icon = updateDto.icon ?? pricing.icon;
      await this.pricingRepo.save(pricing);

      if (updateDto.tiers) {
        pricing.tiers = updateDto.tiers.map(tierDto =>
          this.tierRepo.create({
            ...tierDto,
            pricing,
          }),
        );
        await this.tierRepo.save(pricing.tiers);
      }

      return this.findOne(id);
    } catch (error) {
      if (error instanceof NotFoundException) throw error;
      throw new InternalServerErrorException('Failed to update client pricing');
    }
  }

  async remove(id: number): Promise<void> {
    try {
      const result = await this.pricingRepo.delete(id);
      if (result.affected === 0) throw new NotFoundException(`Pricing with id ${id} not found`);
    } catch (error) {
      if (error instanceof NotFoundException) throw error;
      throw new InternalServerErrorException('Failed to delete client pricing');
    }
  }
}
