/**
 * 学习资料 Repository
 * 提供学习资料的数据访问接口
 */
import type {
  MaterialSubject,
  MaterialFile,
  MaterialFileType,
} from '../../types/material';
import { api } from '../../services/api';

// ==================== 接口定义 ====================

export interface GetMaterialsParams {
  subjectId?: string;
  fileType?: MaterialFileType;
  keyword?: string;
  sortBy?: 'createdAt' | 'downloadCount' | 'title';
  sortOrder?: 'asc' | 'desc';
  page?: number;
  pageSize?: number;
}

export interface MaterialsResult {
  materials: MaterialFile[];
  total: number;
  page: number;
  pageSize: number;
  hasMore: boolean;
}

// ==================== API 响应类型 ====================

interface SubjectResponse {
  id: string;
  name: string;
  icon: string;
  color: string;
  description: string;
  sort_order: number;
  is_active: boolean;
  material_count: number;
  created_at: string;
  updated_at: string;
}

interface MaterialFileResponse {
  id: string;
  subject_id: string;
  title: string;
  description: string;
  file_type: string;
  file_size: number;
  file_url: string;
  file_name: string;
  download_count: number;
  author_id: string;
  tags: string[];
  status: string;
  created_at: string;
  updated_at: string;
  subject?: SubjectResponse;
}

// ==================== 转换函数 ====================

function toMaterialSubject(res: SubjectResponse): MaterialSubject {
  return {
    id: res.id,
    name: res.name,
    icon: res.icon,
    color: res.color,
    description: res.description,
    sort_order: res.sort_order,
    is_active: res.is_active,
    material_count: res.material_count,
    created_at: res.created_at,
    updated_at: res.updated_at,
  };
}

function toMaterialFile(res: MaterialFileResponse): MaterialFile {
  return {
    id: res.id,
    subject_id: res.subject_id,
    title: res.title,
    description: res.description,
    file_type: res.file_type as MaterialFileType,
    file_size: res.file_size,
    file_url: res.file_url,
    file_name: res.file_name,
    download_count: res.download_count,
    author_id: res.author_id,
    tags: res.tags || [],
    status: res.status as 'active' | 'inactive',
    created_at: res.created_at,
    updated_at: res.updated_at,
    subject: res.subject ? toMaterialSubject(res.subject) : undefined,
  };
}

// ==================== Repository 实现 ====================

/**
 * 学习资料数据仓库
 * 使用真实 API
 */
export class MaterialRepository {
  private static instance: MaterialRepository;

  private constructor() {}

  static getInstance(): MaterialRepository {
    if (!MaterialRepository.instance) {
      MaterialRepository.instance = new MaterialRepository();
    }
    return MaterialRepository.instance;
  }

  /**
   * 获取学科分类列表
   */
  async getSubjects(): Promise<MaterialSubject[]> {
    try {
      const response = await api.get<{ list: SubjectResponse[] }>('/materials/subjects');
      return response.data.list.map(toMaterialSubject);
    } catch (error) {
      console.error('获取学科列表失败:', error);
      return [];
    }
  }

  /**
   * 根据ID获取学科详情
   */
  async getSubjectById(id: string): Promise<MaterialSubject | null> {
    try {
      const response = await api.get<SubjectResponse>(`/materials/subjects/${id}`);
      return toMaterialSubject(response.data);
    } catch (error) {
      console.error('获取学科详情失败:', error);
      return null;
    }
  }

  /**
   * 获取资料列表
   */
  async getMaterials(params: GetMaterialsParams): Promise<MaterialsResult> {
    const {
      subjectId,
      fileType,
      keyword,
      sortBy = 'createdAt',
      sortOrder = 'desc',
      page = 1,
      pageSize = 20,
    } = params;

    try {
      const queryParams: Record<string, any> = {
        page,
        page_size: pageSize,
      };

      if (subjectId) {
        queryParams.subject_id = subjectId;
      }
      if (fileType) {
        queryParams.file_type = fileType;
      }
      if (keyword) {
        queryParams.keyword = keyword;
      }

      const response = await api.get<{
        list: MaterialFileResponse[];
        total: number;
        page: number;
        page_size: number;
        has_more: boolean;
      }>('/materials', queryParams);

      return {
        materials: response.data.list.map(toMaterialFile),
        total: response.data.total,
        page: response.data.page,
        pageSize: response.data.page_size,
        hasMore: response.data.has_more,
      };
    } catch (error) {
      console.error('获取资料列表失败:', error);
      return {
        materials: [],
        total: 0,
        page: 1,
        pageSize,
        hasMore: false,
      };
    }
  }

  /**
   * 根据ID获取资料详情
   */
  async getMaterialById(id: string): Promise<MaterialFile | null> {
    try {
      const response = await api.get<MaterialFileResponse>(`/materials/${id}`);
      return toMaterialFile(response.data);
    } catch (error) {
      console.error('获取资料详情失败:', error);
      return null;
    }
  }

  /**
   * 搜索资料
   */
  async searchMaterials(keyword: string, params?: { fileType?: MaterialFileType }): Promise<MaterialsResult> {
    return this.getMaterials({
      keyword,
      fileType: params?.fileType,
    });
  }

  /**
   * 获取热门资料
   */
  async getHotMaterials(limit: number = 10): Promise<MaterialFile[]> {
    try {
      const response = await api.get<{
        list: MaterialFileResponse[];
        total: number;
        page: number;
        page_size: number;
        has_more: boolean;
      }>('/materials', {
        page: 1,
        page_size: limit,
        sort_by: 'download_count',
        sort_order: 'desc',
      });
      return response.data.list.map(toMaterialFile);
    } catch (error) {
      console.error('获取热门资料失败:', error);
      return [];
    }
  }

  /**
   * 获取最新资料
   */
  async getLatestMaterials(limit: number = 10): Promise<MaterialFile[]> {
    try {
      const response = await api.get<{
        list: MaterialFileResponse[];
        total: number;
        page: number;
        page_size: number;
        has_more: boolean;
      }>('/materials', {
        page: 1,
        page_size: limit,
        sort_by: 'created_at',
        sort_order: 'desc',
      });
      return response.data.list.map(toMaterialFile);
    } catch (error) {
      console.error('获取最新资料失败:', error);
      return [];
    }
  }

  /**
   * 获取资料的下载链接（增加下载次数）
   */
  async downloadMaterial(id: string): Promise<{ file_url: string; file_name: string } | null> {
    try {
      const response = await api.get<{ file_url: string; file_name: string }>(`/materials/${id}/download`);
      return response.data;
    } catch (error) {
      console.error('获取下载链接失败:', error);
      return null;
    }
  }
}

// 导出单例
export const materialRepository = MaterialRepository.getInstance();