import fs from "fs";
import path from "path";
import { prisma } from "../../core/prisma";
import { AppError } from "../../core/AppError";
import { STATIC_SOUNDS_DIR } from "../../core/storage-paths";
import type { StationSoundDto } from "ttm-shared";

function toDto(row: any): StationSoundDto {
    return {
        id: row.id,
        stationId: row.stationId,
        event: row.event,
        label: row.label,
        fileName: row.fileName,
        fileUrl: row.fileUrl,
        createdAt: row.createdAt.toISOString(),
    };
}

export const stationSoundService = {
    async list(shopId: string, stationId: string): Promise<StationSoundDto[]> {
        const station = await prisma.station.findFirst({ where: { id: stationId, shopId } });
        if (!station) throw new AppError("Station not found", 404);

        const rows = await prisma.stationSound.findMany({
            where: { stationId },
            orderBy: { createdAt: "asc" },
        });

        return rows.map(toDto);
    },

    async upsert(
        shopId: string,
        stationId: string,
        event: string,
        file: Express.Multer.File,
        label?: string,
    ): Promise<StationSoundDto> {
        const station = await prisma.station.findFirst({ where: { id: stationId, shopId } });
        if (!station) throw new AppError("Station not found", 404);

        // Supprimer l'ancien fichier son si présent
        const existing = await prisma.stationSound.findUnique({
            where: { stationId_event: { stationId, event: event as any } },
        });
        if (existing) {
            const oldFilePath = path.join(STATIC_SOUNDS_DIR, existing.fileName);
            try {
                fs.unlinkSync(oldFilePath);
            } catch {
                // Fichier peut déjà ne plus exister, on ignore
            }
        }

        const fileUrl = `/api/sounds/${file.filename}`;

        const row = await prisma.stationSound.upsert({
            where: { stationId_event: { stationId, event: event as any } },
            create: {
                stationId,
                event: event as any,
                label: label ?? file.originalname,
                fileName: file.filename,
                fileUrl,
            },
            update: {
                label: label ?? file.originalname,
                fileName: file.filename,
                fileUrl,
            },
        });

        return toDto(row);
    },

    async remove(shopId: string, stationId: string, soundId: string): Promise<void> {
        const station = await prisma.station.findFirst({ where: { id: stationId, shopId } });
        if (!station) throw new AppError("Station not found", 404);

        const sound = await prisma.stationSound.findFirst({ where: { id: soundId, stationId } });
        if (!sound) throw new AppError("Sound not found", 404);

        const filePath = path.join(STATIC_SOUNDS_DIR, sound.fileName);
        try {
            fs.unlinkSync(filePath);
        } catch {
            // Pas grave si manquant
        }

        await prisma.stationSound.delete({ where: { id: soundId } });
    },
};

