import { Injectable, NotFoundException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { rm } from "fs/promises";
import { join } from "path";
import { Repository } from "typeorm";
import { UpdateMediaDto } from "./dto/update-media.dto";
import { MediaAsset } from "./entities/media-asset.entity";

@Injectable()
export class MediaService {
  constructor(@InjectRepository(MediaAsset) private readonly repo: Repository<MediaAsset>) {}

  record(file: Express.Multer.File): Promise<MediaAsset> {
    const asset = this.repo.create({
      fileName: file.filename,
      originalName: file.originalname,
      url: `/uploads/${file.filename}`,
      mimeType: file.mimetype,
      sizeBytes: file.size,
    });
    return this.repo.save(asset);
  }

  async list(
    search?: string,
    page = 1,
    pageSize = 32,
  ): Promise<{ items: MediaAsset[]; total: number; page: number; pageSize: number }> {
    const qb = this.repo.createQueryBuilder("asset").orderBy("asset.createdAt", "DESC");
    const q = search?.trim();
    if (q) qb.where("asset.originalName LIKE :q", { q: `%${q}%` });

    const safePage = Math.max(1, page);
    const safePageSize = Math.min(100, Math.max(1, pageSize));
    qb.skip((safePage - 1) * safePageSize).take(safePageSize);

    const [items, total] = await qb.getManyAndCount();
    return { items, total, page: safePage, pageSize: safePageSize };
  }

  async update(id: string, dto: UpdateMediaDto): Promise<MediaAsset> {
    const asset = await this.repo.findOneBy({ id });
    if (!asset) throw new NotFoundException("Media asset not found.");
    if (dto.originalName !== undefined) asset.originalName = dto.originalName;
    if (dto.altText !== undefined) asset.altText = dto.altText || null;
    return this.repo.save(asset);
  }

  async remove(id: string): Promise<void> {
    const asset = await this.repo.findOneBy({ id });
    if (!asset) throw new NotFoundException("Media asset not found.");
    await rm(join(process.cwd(), "uploads", asset.fileName), { force: true });
    await this.repo.remove(asset);
  }
}
