import { BadGatewayException, Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import axios from 'axios';
import {
  CourseResourceItem,
  CourseResourcesPayload,
  DatawhaleCourseRow,
} from './course_resources.types';

const DATAWHALE_LEARN_API = 'https://backend.datawhale.cn/api/learn/v2/queryLearnPage';
const DATAWHALE_COURSE_DETAIL_URL = 'https://www.datawhale.cn/learn/summary';
const DEFAULT_PAGE_SIZE = 12;

const DIFFICULTY_LABELS: Record<string, string> = {
  BEGINNER: '初级',
  INTERMEDIATE: '中级',
  ADVANCED: '高级',
  OTHER: '其他',
};

const CATEGORY_LABELS: Record<string, string> = {
  GITHUB_TUTORIAL: 'github开源教程',
  AI_PLUS_X: '高校行',
  LEARN_CAMP: '学习营',
  COMPETITION_TUTORIAL: '竞赛教程',
  TEENAGER: '青少年',
  AI_EDUCATION_POPULARIZATION: 'AI教育与科普',
  AI_TOOL_APPLICATION: 'AI工具应用',
  PROGRAMMING_BASICS: '编程基础',
  AI_APPLICATION_DEVELOPMENT: 'AI应用开发',
  AI_PLUS_X_PROFESSIONAL: 'AI+X专业领域',
  AI_CORE_PRINCIPLES: '人工智能核心原理',
  OTHER: '其他',
};

@Injectable()
export class CourseResourcesService implements OnModuleInit {
  private readonly logger = new Logger(CourseResourcesService.name);
  private courses: CourseResourceItem[] = [];
  private syncedAt: Date | null = null;
  private syncing: Promise<void> | null = null;

  async onModuleInit(): Promise<void> {
    this.syncNow().catch(error => {
      this.logger.warn(`Datawhale课程启动同步失败：${this.errorMessage(error)}`);
    });
  }

  @Cron('0 3 * * *')
  async syncDaily(): Promise<void> {
    await this.syncNow();
  }

  async getDatawhaleCourses(): Promise<CourseResourcesPayload> {
    if (this.courses.length === 0) {
      await this.syncNow();
    }

    return {
      source: 'datawhale',
      courses: this.courses,
      total: this.courses.length,
      syncedAt: this.syncedAt ? this.syncedAt.toISOString() : null,
    };
  }

  async syncNow(): Promise<CourseResourcesPayload> {
    if (this.syncing) {
      await this.syncing;
      return this.getCachedPayload();
    }

    this.syncing = this.fetchAndReplace();
    try {
      await this.syncing;
    } finally {
      this.syncing = null;
    }
    return this.getCachedPayload();
  }

  private getCachedPayload(): CourseResourcesPayload {
    return {
      source: 'datawhale',
      courses: this.courses,
      total: this.courses.length,
      syncedAt: this.syncedAt ? this.syncedAt.toISOString() : null,
    };
  }

  private async fetchAndReplace(): Promise<void> {
    try {
      const response = await axios.get(DATAWHALE_LEARN_API, {
        params: {
          page: 1,
          size: DEFAULT_PAGE_SIZE,
          sort: 'listpagePrio,createTime,desc',
        },
        timeout: 15000,
      });
      const rows = response.data?.data?.rows;
      if (!Array.isArray(rows)) {
        throw new BadGatewayException('Datawhale课程接口返回格式异常');
      }

      this.courses = rows.map((row: DatawhaleCourseRow) => this.normalizeCourse(row));
      this.syncedAt = new Date();
      this.logger.log(`Datawhale课程同步完成，共 ${this.courses.length} 条`);
    } catch (error) {
      if (this.courses.length > 0) {
        this.logger.warn(`Datawhale课程同步失败，继续使用缓存：${this.errorMessage(error)}`);
        return;
      }
      throw error;
    }
  }

  private normalizeCourse(row: DatawhaleCourseRow): CourseResourceItem {
    const category = row.category || 'OTHER';
    const difficulty = row.difficulty || 'OTHER';
    const id = Number(row.id || 0);
    return {
      id,
      title: row.title || '未命名课程',
      intro: row.intro || '',
      coverUrl: row.coverUrl || '',
      category,
      categoryLabel: CATEGORY_LABELS[category] || category,
      difficulty,
      difficultyLabel: DIFFICULTY_LABELS[difficulty] || difficulty,
      viewCount: Number(row.viewCount || 0),
      detailUrl: `${DATAWHALE_COURSE_DETAIL_URL}/${id}`,
      source: 'datawhale',
      updatedAt: row.updateTime,
    };
  }

  private errorMessage(error: unknown): string {
    if (error instanceof Error) {
      return error.message;
    }
    return String(error);
  }
}
