import { ConfigsService } from '@/modules/bids/services/configs.service';
import { DashboardService } from '@/modules/bids/services/dashboard.service';
import { MailsService } from '@/modules/mails/services/mails.service';
import { delay } from '@/ultils';
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import * as moment from 'moment';
import { Between } from 'typeorm';
import { ScrapItemsService } from './scrap-item-config.service';
import { HotItemApi } from '@/modules/bids/apis/hot-item.api';

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

  constructor(
    private readonly scrapItemsService: ScrapItemsService,
    private readonly mailsService: MailsService,
    private readonly configsSerivce: ConfigsService,
    private readonly dashboardService: DashboardService,
    private readonly hotItemApi: HotItemApi,
  ) {}

  async runProcessAndSendReport(processName: string) {
    const mails = (await this.configsSerivce.getConfig('MAIL_SCRAP_REPORT'))
      ?.value;
    if (!mails) {
      console.warn('No mails configured for report. Skipping.');
      return;
    }

    // Nếu process đang chạy, không chạy lại
    const initialStatus =
      await this.dashboardService.getStatusProcessByName(processName);
    if (initialStatus === 'online') {
      console.log(
        `Process ${processName} is already running. Skipping execution.`,
      );
      return;
    }

    // Reset và chạy process
    await this.dashboardService.resetProcessByName(processName);
    console.log(`Process ${processName} started.`);

    // Đợi process kết thúc, có timeout
    const maxAttempts = 60; // 10 phút
    let attempts = 0;
    let status = 'online';

    while (status === 'online' && attempts < maxAttempts) {
      await delay(10000); // 10 giây
      status = await this.dashboardService.getStatusProcessByName(processName);
      attempts++;
    }

    if (status === 'online') {
      console.warn(
        `Process ${processName} still running after timeout. Skipping report.`,
      );
      return;
    }

    // Khi process kết thúc => gửi mail
    const startOfDay = new Date();
    startOfDay.setHours(0, 0, 0, 0);
    const endOfDay = new Date();
    endOfDay.setHours(23, 59, 59, 999);

    try {
      const data = await this.scrapItemsService.scrapItemRepo.find({
        where: {
          updated_at: Between(startOfDay, endOfDay),
        },
        relations: { scrap_config: { web_bid: true } },
        order: { updated_at: 'DESC' },
      });

      const hotItems = await this.hotItemApi.listHotItem();

      const { hasHotItem, html } = this.mailsService.generateProductTableHTML(
        data,
        hotItems,
      );

      await this.mailsService.sendHtmlMailJob({
        to: mails,
        subject: `${hasHotItem ? '[HOT ITEMS] ' : ''}Auction Items Matching Your Keywords – Daily Update ${moment().format('YYYY-MM-DD HH:mm')}`,
        html: html,
      });

      console.log('Report mail sent successfully.');
    } catch (err) {
      console.error('Failed to generate or send report:', err);
    }
  }

  // Thực hiện gọi scrape vào lúc 8h59 (giờ ÚC) mỗi ngày
  @Cron('59 5 * * *')
  async handleScraps() {
    const processName = 'scrape-data-keyword';
    await this.runProcessAndSendReport(processName);
  }
}
