import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ClsService } from 'nestjs-cls';
import { ConfigService } from '@nestjs/config';
import { TenantSettingsEntity } from '../../entities/tenant-settings.entity';
import { UpdateSettingsDto } from './dto/update-settings.dto';
import { CLS_TENANT_ID, CLS_USER_ID } from '../../common/cls/cls.constants';
import { serviceMessages } from '../../common/constants/messages';

const MSG = serviceMessages('Settings');

@Injectable()
export class SettingsService {
  constructor(
    @InjectRepository(TenantSettingsEntity)
    private readonly settingsRepo: Repository<TenantSettingsEntity>,
    private readonly cls: ClsService,
    private readonly config: ConfigService,
  ) {}

  private getTenantId(): string {
    return this.cls.get<string>(CLS_TENANT_ID);
  }

  private getUserId(): string | null {
    return this.cls.get<string>(CLS_USER_ID) || null;
  }

  /**
   * Convert relative logo path to absolute URL.
   * Handles both relative paths (/api/uploads/...) and already-absolute URLs.
   */
  private toAbsoluteUrl(path: string | null): string | null {
    if (!path) return null;
    // Already absolute URL (http/https)
    if (path.startsWith('http://') || path.startsWith('https://')) return path;
    // Relative path - concatenate with BASE_URL from env
    const baseUrl = this.config.get<string>('app.baseUrl', 'http://localhost:3000');
    return path.startsWith('/') ? `${baseUrl}${path}` : `${baseUrl}/${path}`;
  }

  /**
   * Public branding — returns only colors + logo + company name for login page.
   */
  async getBranding() {
    const tenantId = this.getTenantId();
    const settings = await this.settingsRepo.findOne({
      where: { tenant_id: tenantId, is_deleted: false },
      select: {
        company_name: true,
        logo_url: true,
        primary_color: true,
        secondary_color: true,
      },
    });

    return {
      company_name: settings?.company_name || null,
      logo_url: this.toAbsoluteUrl(settings?.logo_url || null),
      primary_color: settings?.primary_color || '#10b981',
      secondary_color: settings?.secondary_color || '#1e293b',
    };
  }

  async get() {
    const tenantId = this.getTenantId();
    const settings = await this.settingsRepo.findOne({
      where: { tenant_id: tenantId, is_deleted: false },
      relations: {
        default_currency: true,
      },
    });

    if (!settings) {
      throw new NotFoundException(MSG.NOT_FOUND);
    }

    // Convert logo_url to absolute URL
    return {
      ...settings,
      logo_url: this.toAbsoluteUrl(settings.logo_url),
    };
  }

  async update(dto: UpdateSettingsDto) {
    const tenantId = this.getTenantId();
    const userId = this.getUserId();

    const settings = await this.settingsRepo.findOne({
      where: { tenant_id: tenantId, is_deleted: false },
    });

    if (!settings) {
      throw new NotFoundException(MSG.NOT_FOUND);
    }

    // Merge updates
    Object.assign(settings, dto, { updated_by: userId });
    await this.settingsRepo.save(settings);

    return { message: MSG.UPDATED };
  }
}
