import { Injectable, NotFoundException, ForbiddenException, Logger } from '@nestjs/common';
import { PrismaService } from '../../database/prisma.service';
import { CreateLibraryDto, UpdateLibraryDto, CreateResourceItemDto, UpdateResourceItemDto } from './dto/create-resource.dto';

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

  constructor(private prisma: PrismaService) {}

  // ==================== 工具方法 ====================

  private parseJsonArray(value: any): any[] {
    if (!value) return [];
    if (typeof value === 'string') {
      try {
        return JSON.parse(value);
      } catch {
        return [];
      }
    }
    return Array.isArray(value) ? value : [];
  }

  // ==================== 资源库管理 ====================

  async findAllLibraries(query: any) {
    const { page = 1, pageSize = 10, libraryType, keyword } = query;

    const skip = (page - 1) * pageSize;
    const take = +pageSize;

    const where: any = {};

    if (libraryType) {
      where.libraryType = libraryType;
    }

    if (keyword) {
      where.name = { contains: keyword };
    }

    const [items, total] = await Promise.all([
      this.prisma.resourceLibrary.findMany({
        where,
        skip,
        take,
        orderBy: [{ sortOrder: 'asc' }, { createdAt: 'desc' }],
        include: {
          _count: {
            select: {
              items: true,
            },
          },
        },
      }),
      this.prisma.resourceLibrary.count({ where }),
    ]);

    return {
      items: items.map((lib) => ({
        ...lib,
        itemCount: lib._count.items,
        _count: undefined,
      })),
      total,
      page: +page,
      pageSize: +pageSize,
    };
  }

  async findLibrary(id: number) {
    const library = await this.prisma.resourceLibrary.findUnique({
      where: { id },
      include: {
        items: {
          orderBy: { sortOrder: 'asc' },
          take: 100,
        },
      },
    });

    if (!library) {
      throw new NotFoundException('资源库不存在');
    }

    return {
      ...library,
      items: library.items.map((item) => ({
        ...item,
        tags: this.parseJsonArray(item.tags),
      })),
    };
  }

  async createLibrary(dto: CreateLibraryDto, userId: number) {
    const library = await this.prisma.resourceLibrary.create({
      data: {
        name: dto.name,
        libraryType: dto.libraryType,
        description: dto.description,
        coverImage: dto.coverImage,
        createdBy: userId,
      },
    });

    this.logger.log(`Library created: ${library.id}`);

    return library;
  }

  async updateLibrary(id: number, dto: UpdateLibraryDto) {
    const library = await this.prisma.resourceLibrary.findUnique({
      where: { id },
    });

    if (!library) {
      throw new NotFoundException('资源库不存在');
    }

    const updated = await this.prisma.resourceLibrary.update({
      where: { id },
      data: {
        name: dto.name,
        description: dto.description,
        coverImage: dto.coverImage,
        sortOrder: dto.sortOrder,
      },
    });

    this.logger.log(`Library updated: ${id}`);

    return updated;
  }

  async deleteLibrary(id: number) {
    const library = await this.prisma.resourceLibrary.findUnique({
      where: { id },
      include: {
        _count: {
          select: {
            items: true,
          },
        },
      },
    });

    if (!library) {
      throw new NotFoundException('资源库不存在');
    }

    // 删除资源库（会级联删除所有资源项目）
    await this.prisma.resourceLibrary.delete({
      where: { id },
    });

    this.logger.log(`Library deleted: ${id}`);

    return { message: '删除成功' };
  }

  // ==================== 资源项目管理 ====================

  async findAllItems(query: any) {
    const { page = 1, pageSize = 20, libraryId, fileType, keyword } = query;

    const skip = (page - 1) * pageSize;
    const take = +pageSize;

    const where: any = {};

    if (libraryId) {
      where.libraryId = +libraryId;
    }

    if (fileType) {
      where.fileType = fileType;
    }

    if (keyword) {
      where.OR = [
        { title: { contains: keyword } },
        { description: { contains: keyword } },
      ];
    }

    const [items, total] = await Promise.all([
      this.prisma.resourceItem.findMany({
        where,
        skip,
        take,
        orderBy: [{ sortOrder: 'asc' }, { createdAt: 'desc' }],
        include: {
          library: {
            select: {
              id: true,
              name: true,
              libraryType: true,
            },
          },
        },
      }),
      this.prisma.resourceItem.count({ where }),
    ]);

    return {
      items: items.map((item) => ({
        ...item,
        tags: this.parseJsonArray(item.tags),
      })),
      total,
      page: +page,
      pageSize: +pageSize,
    };
  }

  async findItem(id: number) {
    const item = await this.prisma.resourceItem.findUnique({
      where: { id },
      include: {
        library: {
          select: {
            id: true,
            name: true,
            libraryType: true,
          },
        },
      },
    });

    if (!item) {
      throw new NotFoundException('资源项目不存在');
    }

    return {
      ...item,
      tags: this.parseJsonArray(item.tags),
    };
  }

  async createItem(dto: CreateResourceItemDto) {
    // 检查资源库是否存在
    const library = await this.prisma.resourceLibrary.findUnique({
      where: { id: dto.libraryId },
    });

    if (!library) {
      throw new NotFoundException('资源库不存在');
    }

    const item = await this.prisma.resourceItem.create({
      data: {
        libraryId: dto.libraryId,
        title: dto.title,
        description: dto.description,
        fileType: dto.fileType,
        filePath: dto.filePath,
        fileSize: dto.fileSize,
        tags: JSON.stringify(dto.tags || []),
      },
    });

    this.logger.log(`Resource item created: ${item.id}`);

    return {
      ...item,
      tags: this.parseJsonArray(item.tags),
    };
  }

  async updateItem(id: number, dto: UpdateResourceItemDto) {
    const item = await this.prisma.resourceItem.findUnique({
      where: { id },
    });

    if (!item) {
      throw new NotFoundException('资源项目不存在');
    }

    const updated = await this.prisma.resourceItem.update({
      where: { id },
      data: {
        title: dto.title,
        description: dto.description,
        tags: dto.tags ? JSON.stringify(dto.tags) : undefined,
        sortOrder: dto.sortOrder,
      },
    });

    this.logger.log(`Resource item updated: ${id}`);

    return {
      ...updated,
      tags: this.parseJsonArray(updated.tags),
    };
  }

  async deleteItem(id: number) {
    const item = await this.prisma.resourceItem.findUnique({
      where: { id },
    });

    if (!item) {
      throw new NotFoundException('资源项目不存在');
    }

    await this.prisma.resourceItem.delete({
      where: { id },
    });

    this.logger.log(`Resource item deleted: ${id}`);

    return { message: '删除成功' };
  }

  async batchDeleteItems(ids: number[]) {
    await this.prisma.resourceItem.deleteMany({
      where: {
        id: { in: ids },
      },
    });

    this.logger.log(`Batch deleted ${ids.length} resource items`);

    return { message: `成功删除 ${ids.length} 个资源` };
  }

  // ==================== 统计数据 ====================

  async getStats() {
    const [totalLibraries, totalItems, itemsByType, itemsByLibraryType] = await Promise.all([
      this.prisma.resourceLibrary.count(),
      this.prisma.resourceItem.count(),
      this.prisma.resourceItem.groupBy({
        by: ['fileType'],
        _count: true,
      }),
      this.prisma.resourceLibrary.groupBy({
        by: ['libraryType'],
        _count: true,
      }),
    ]);

    return {
      totalLibraries,
      totalItems,
      itemsByType: itemsByType.reduce((acc, item) => {
        acc[item.fileType] = item._count;
        return acc;
      }, {} as Record<string, number>),
      itemsByLibraryType: itemsByLibraryType.reduce((acc, lib) => {
        acc[lib.libraryType] = lib._count;
        return acc;
      }, {} as Record<string, number>),
    };
  }
}
