import {
  Injectable,
  NotFoundException,
  BadRequestException,
  ConflictException,
  Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { PublicSiteConfig } from '../../entities/public-site-config.entity';
import { License } from '../../entities/license.entity';
import { UpdatePublicSiteDto } from './dto/update-public-site.dto';
import { UpdateDomainDto } from './dto/update-domain.dto';

@Injectable()
export class SettingsService {
  private readonly logger = new Logger(SettingsService.name);

  constructor(
    @InjectRepository(PublicSiteConfig)
    private publicSiteConfigRepository: Repository<PublicSiteConfig>,
    @InjectRepository(License)
    private licenseRepository: Repository<License>,
  ) {}

  async getPublicSite(licenseId: string): Promise<PublicSiteConfig> {
    let config = await this.publicSiteConfigRepository.findOne({
      where: { license_id: licenseId },
    });

    // Create default config if not exists
    if (!config) {
      config = this.publicSiteConfigRepository.create({
        license_id: licenseId,
        site_enabled: false,
        show_on_status_page: false,
        steam_connect_url: null,
        motd: null,
        public_mods: [],
        header_image_url: null,
        theme_color: '#1a1a1a',
        discord_invite_url: null,
        show_player_count: true,
        show_wipe_schedule: true,
        show_wipe_countdown: true,
        show_mod_list: true,
        status_page_description: null,
      });

      config = await this.publicSiteConfigRepository.save(config);
    }

    return config;
  }

  async updatePublicSite(
    licenseId: string,
    dto: UpdatePublicSiteDto,
  ): Promise<PublicSiteConfig> {
    // Ensure config exists first
    let config = await this.getPublicSite(licenseId);

    // Update fields
    Object.assign(config, dto);

    return await this.publicSiteConfigRepository.save(config);
  }

  async updateDomain(licenseId: string, dto: UpdateDomainDto) {
    const license = await this.licenseRepository.findOne({
      where: { id: licenseId },
    });

    if (!license) {
      throw new NotFoundException(`License ${licenseId} not found`);
    }

    // Check if subdomain is already taken (if changing subdomain)
    if (dto.subdomain && dto.subdomain !== license.subdomain) {
      const existingSubdomain = await this.licenseRepository.findOne({
        where: { subdomain: dto.subdomain },
      });

      if (existingSubdomain) {
        throw new ConflictException(
          `Subdomain "${dto.subdomain}" is already taken`,
        );
      }

      // Validate subdomain format
      if (dto.subdomain.length < 3 || dto.subdomain.length > 63) {
        throw new BadRequestException(
          'Subdomain must be between 3 and 63 characters',
        );
      }

      if (dto.subdomain.startsWith('-') || dto.subdomain.endsWith('-')) {
        throw new BadRequestException(
          'Subdomain cannot start or end with a hyphen',
        );
      }

      this.logger.warn(
        `Cloudflare DNS integration not configured — subdomain ${dto.subdomain} updated in DB only`,
      );
      license.subdomain = dto.subdomain;
    }

    // Update custom domain if provided
    if (dto.custom_domain !== undefined) {
      if (dto.custom_domain && dto.custom_domain !== license.custom_domain) {
        // Validate domain format (basic check)
        const domainRegex = /^([a-z0-9-]+\.)+[a-z]{2,}$/i;
        if (!domainRegex.test(dto.custom_domain)) {
          throw new BadRequestException('Invalid custom domain format');
        }

        this.logger.warn(
          `Cloudflare DNS integration not configured — custom domain ${dto.custom_domain} updated in DB only`,
        );
        license.custom_domain = dto.custom_domain;
      } else if (dto.custom_domain === null || dto.custom_domain === '') {
        // Allow clearing custom domain
        license.custom_domain = null;
      }
    }

    const updated = await this.licenseRepository.save(license);

    return {
      subdomain: updated.subdomain,
      custom_domain: updated.custom_domain,
      subdomain_url: updated.subdomain
        ? `https://${updated.subdomain}.corrosionmgmt.com`
        : null,
      custom_domain_url: updated.custom_domain
        ? `https://${updated.custom_domain}`
        : null,
    };
  }
}
