import { NextResponse } from 'next/server';
import fs from 'fs-extra';
import path from 'path';
import { getFlacMetadata, parseLabel } from '@/lib/utils/audio';
import { AnalysisTrack, ApiResponse, AlbumResponse } from '@/types';

export async function POST(request: Request) {
    try {
        const { albumPath, releaseType } = await request.json();

        if (!albumPath || !(await fs.pathExists(albumPath))) {
            return NextResponse.json({ error: 'Invalid album path' }, { status: 400 });
        }

        const files = await fs.readdir(albumPath);
        const flacFiles = files.filter((file) => file.toLowerCase().endsWith('.flac'));

        if (flacFiles.length === 0) {
            return NextResponse.json({ error: 'No FLAC files found' }, { status: 400 });
        }

        const tracks: AnalysisTrack[] = await Promise.all(
            flacFiles.map(async (file) => {
                const filePath = path.join(albumPath, file);
                const metadata = await getFlacMetadata(filePath);
                return {
                    filename: file,
                    path: filePath,
                    ...metadata,
                };
            })
        );

        // Sort tracks
        tracks.sort((a, b) => {
            if ('error' in a || 'error' in b) return 0;
            const trackA = a.common?.track?.no ?? 0;
            const trackB = b.common?.track?.no ?? 0;
            if (trackA && trackB) return trackA - trackB;
            return a.filename.localeCompare(b.filename);
        });

        // Analyze quality for description
        let isLossless = true;
        let isHiRes = true;
        let mixed = false;
        let qualityDetails = '';
        const sampleRates = new Set();
        const bitDepths = new Set();

        tracks.forEach((track) => {
            if ('error' in track) return;
            const sr = track.format?.sampleRate;
            const bd = track.format?.bitsPerSample;
            if (sr) sampleRates.add(sr);
            if (bd) bitDepths.add(bd);
            if (sr !== 44100 || bd !== 16) isLossless = false;
            if (!sr || sr < 48000 || !bd || bd < 24) isHiRes = false;
        });

        if (sampleRates.size > 1 || bitDepths.size > 1) {
            mixed = true;
            qualityDetails = `\n\nNOTE: Mixed formats. Sample Rates: ${Array.from(sampleRates).join(', ')} Hz. Bit Depths: ${Array.from(bitDepths).join(', ')} bit.`;

            const mixedDetails = tracks.map(t => {
                if ('error' in t) return `${t.filename}: Error`;
                return `Track ${t.common?.track?.no || '?'}: ${t.format?.bitsPerSample}bit / ${t.format?.sampleRate}Hz`;
            }).join('\n');

            qualityDetails += '\n' + mixedDetails;
        }

        const firstTrack = tracks.find((t): t is Extract<AnalysisTrack, { error?: never }> => !('error' in t));
        if (!firstTrack) {
            return NextResponse.json({ error: 'No valid tracks found' }, { status: 400 });
        }

        const albumName = firstTrack.common?.album || 'Unknown Album';
        const year = firstTrack.common?.year || (firstTrack.common?.date ? parseInt(firstTrack.common.date.split('-')[0]) : 2025);

        let label = parseLabel(firstTrack.common?.copyright || '');

        const upc = firstTrack.native?.vorbis?.find(tag => tag.id === 'UPC')?.value || firstTrack.common?.barcode || '';

        // Artists
        // Artists Logic

        // Helper to split artists
        const splitArtists = (artistString: string) => {
            return artistString.split(/,\s+|\s+\/\s+|;\s+/).map((a: string) => a.trim()).filter((a: string) => a.length > 0);
        };

        // Collect all artists and their frequencies
        const artistCounts = new Map<string, number>();
        const allUniqueArtists = new Set<string>();

        tracks.forEach(t => {
            if ('error' in t) return;
            let trackArtists: string[] = [];
            // music-metadata might return artists as an array, but sometimes elements are comma-separated strings
            if (t.common?.artists) {
                t.common.artists.forEach((a: string) => trackArtists.push(...splitArtists(a)));
            } else if (t.common?.artist) {
                trackArtists = splitArtists(t.common.artist);
            }

            trackArtists.forEach(a => {
                allUniqueArtists.add(a);
                artistCounts.set(a, (artistCounts.get(a) || 0) + 1);
            });
        });

        let mainArtists: { name: string }[] = [];
        const withArtists: { name: string }[] = [];

        if (releaseType === 7) {
            // Compilation: All artists in mainArtists, no withArtists
            allUniqueArtists.forEach(a => {
                if (a !== 'Various Artists') {
                    mainArtists.push({ name: a });
                }
            });
        } else {
            // Standard Logic
            // Determine Main Artist String
            let mainArtistName = firstTrack.common?.albumartist || 'Various Artists';

            // If album artist is Various Artists (or missing), find the most common artist
            if (mainArtistName === 'Various Artists' || !mainArtistName) {
                let maxCount = 0;
                let mostFrequent = '';
                artistCounts.forEach((count, artist) => {
                    if (count > maxCount) {
                        maxCount = count;
                        mostFrequent = artist;
                    }
                });
                if (mostFrequent) {
                    mainArtistName = mostFrequent;
                }
            }

            // Split main artist into components for the array
            // Use the same split logic as above
            const mainArtistComponents = splitArtists(mainArtistName);
            mainArtists = mainArtistComponents.map(name => ({ name }));

            // Determine With Artists
            allUniqueArtists.forEach(a => {
                // Exclude all main artist components and "Various Artists" from "with" list
                if (!mainArtistComponents.includes(a) && a !== 'Various Artists') {
                    withArtists.push({ name: a });
                }
            });
        }

        // Tracklist
        const tracklist = tracks.map(t => {
            if ('error' in t) return `${t.filename} (Error)`;
            return `${t.common?.track?.no || '00'}. ${t.common?.title || t.filename}`;
        }).join('\n');

        // Description
        let description = "Sourced from TIDAL";
        if (mixed) {
            description += qualityDetails;
        }

        // Encoding
        let encoding = "Lossless";
        const maxBitDepth = Math.max(...Array.from(bitDepths).map(Number));
        if (maxBitDepth >= 24) {
            encoding = "24bit Lossless";
        }

        const response = {
            status: "success",
            response: {
                source: "Crossfade",
                group: {
                    wikiBody: tracklist,
                    bbBody: tracklist,
                    name: albumName,
                    year: year,
                    categoryId: 1,
                    releaseType: releaseType || 1, // Default to Album (1)
                    categoryName: "Music",
                    musicInfo: {
                        composers: [],
                        dj: [],
                        artists: mainArtists,
                        with: withArtists,
                        conductor: [],
                        remixedBy: [],
                        producer: []
                    },
                    recordLabel: label,
                    catalogueNumber: upc,
                    tags: [] // Empty for now, hard to guess
                },
                torrent: {
                    media: "WEB",
                    format: "FLAC",
                    encoding: encoding,
                    //remastered: true,
                    remasterYear: year,
                    remasterRecordLabel: label,
                    remasterCatalogueNumber: upc,
                    description: description,
                    //fileCount: tracks.length,
                    //filePath: `${mainArtistName} - ${albumName} (${year}) [FLAC]`
                }
            }
        };

        return NextResponse.json(response);

    } catch (error) {
        console.error('Error generating RED template:', error);
        return NextResponse.json({ error: 'Failed to generate template' }, { status: 500 });
    }
}
