import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Content } from '../entities/content.entity';
import { Theme } from '../entities/theme.entity';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class CmsService {
  constructor(
    @InjectRepository(Content)
    private contentRepository: Repository<Content>,
    @InjectRepository(Theme)
    private themeRepository: Repository<Theme>,
    private configService: ConfigService,
  ) {}

  async createContent(data: any): Promise<Content> {
    const content = this.contentRepository.create(data);
    const result = await this.contentRepository.insert(content);
    return await this.contentRepository.findOne({ where: { id: result.identifiers[0].id } });
  }

  async updateContent(id: string, data: any): Promise<Content> {
    await this.contentRepository.update(id, data);
    return this.contentRepository.findOne({ where: { id } });
  }

  async deleteContent(id: string): Promise<void> {
    await this.contentRepository.delete(id);
  }

  async getContentBySection(section: string): Promise<Content[]> {
    return this.contentRepository.find({
      where: { section, isActive: true },
      order: { sortOrder: 'ASC' },
    });
  }

  async getContentByKey(key: string): Promise<Content> {
    return this.contentRepository.findOne({
      where: { key, isActive: true },
    });
  }

  async getAllContent(): Promise<Content[]> {
    return this.contentRepository.find({
      where: { isActive: true },
      order: { section: 'ASC', sortOrder: 'ASC' },
    });
  }

  async getContentByType(type: string): Promise<Content[]> {
    return this.contentRepository.find({
      where: { type, isActive: true },
      order: { section: 'ASC', sortOrder: 'ASC' },
    });
  }

  async updateContentByKey(key: string, data: any): Promise<Content> {
    const content = await this.getContentByKey(key);
    if (!content) {
      throw new Error(`Content with key '${key}' not found`);
    }
    return this.updateContent(content.id, data);
  }

  async bulkUpdateContent(updates: Array<{ key: string; value: string; image?: string }>): Promise<Content[]> {
    const updatedContents: Content[] = [];
    
    for (const update of updates) {
      const content = await this.getContentByKey(update.key);
      if (content) {
        const updatedContent = await this.updateContent(content.id, {
          value: update.value,
          ...(update.image && { image: update.image }),
        });
        updatedContents.push(updatedContent);
      }
    }
    
    return updatedContents;
  }

  async getPublicPageContent(page: string): Promise<Record<string, any>> {
    const content = await this.getContentBySection(page);
    const result: Record<string, any> = {};
    
    for (const item of content) {
      if (item.type === 'image') {
        result[item.key] = item.image || item.value;
      } else {
        result[item.key] = item.value;
      }
    }
    
    return result;
  }

  async getTheme(): Promise<Theme> {
    return this.themeRepository.findOne({
      order: { createdAt: 'DESC' },
    });
  }

  async updateTheme(data: any): Promise<Theme> {
    const theme = await this.getTheme();
    if (!theme) {
      return this.themeRepository.save(data);
    }
    return this.themeRepository.save({ ...theme, ...data });
  }

  async backupContent(): Promise<void> {
    const content = await this.contentRepository.find();
    const theme = await this.getTheme();

    // Save backup to storage
    await this.saveBackup({
      content,
      theme,
      timestamp: new Date().toISOString(),
    });
  }

  private async saveBackup(data: any): Promise<void> {
    const backupPath = this.configService.get('BACKUP_PATH');
    const filename = `backup-${new Date().toISOString()}.json`;
    
    // Save backup to storage (implement storage logic here)
    // This would typically use AWS S3 or similar service
  }

  async restoreBackup(filename: string): Promise<void> {
    // Implement backup restoration logic
    // This would typically read from storage and restore content
  }
}
