package utils

import (
	"fmt"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
)

// ParseSelectionFilename parses a selection filename to extract base filename and time bounds
// Format: {base_filename}-{start_seconds}-{end_seconds}.{ext}
// Example: "A05-20250517_214501-102.5-133.7.wav" -> ("A05-20250517_214501", 102.5, 133.7, nil)
func ParseSelectionFilename(filename string) (baseFilename string, startS, endS float64, err error) {
	// Remove file extension
	nameWithoutExt := strings.TrimSuffix(filename, filepath.Ext(filename))

	// Split on dashes from the end
	// We need to find the last 2 dashes that separate times
	parts := strings.Split(nameWithoutExt, "-")

	if len(parts) < 3 {
		return "", 0, 0, fmt.Errorf("invalid selection filename format (expected at least 3 dash-separated parts): %s", filename)
	}

	// Last two parts are end_time and start_time
	endTimeStr := parts[len(parts)-1]
	startTimeStr := parts[len(parts)-2]

	// Everything before is the base filename
	baseFilename = strings.Join(parts[:len(parts)-2], "-")

	// Parse times
	startS, err = strconv.ParseFloat(startTimeStr, 64)
	if err != nil {
		return "", 0, 0, fmt.Errorf("invalid start time '%s': %w", startTimeStr, err)
	}

	endS, err = strconv.ParseFloat(endTimeStr, 64)
	if err != nil {
		return "", 0, 0, fmt.Errorf("invalid end time '%s': %w", endTimeStr, err)
	}

	// Validate: start < end
	if startS >= endS {
		return "", 0, 0, fmt.Errorf("start time (%.2f) must be less than end time (%.2f)", startS, endS)
	}

	return baseFilename, startS, endS, nil
}

// ParseMLFolderName parses the root folder name to extract filter name and date
// Format: Clips_{filter_name}_{YYYY-MM-DD}
// Example: "Clips_opensoundscape-kiwi-1.0_2025-11-14" -> ("opensoundscape-kiwi-1.0", "2025-11-14", nil)
func ParseMLFolderName(folderName string) (filterName string, date string, err error) {
	// Regex: Clips_{anything}_{YYYY-MM-DD}
	// The filter name is everything between "Clips_" and the final underscore+date
	pattern := regexp.MustCompile(`^Clips_(.+)_(\d{4}-\d{2}-\d{2})$`)
	matches := pattern.FindStringSubmatch(folderName)

	if len(matches) != 3 {
		return "", "", fmt.Errorf("invalid ML folder name format (expected 'Clips_{filter_name}_{YYYY-MM-DD}'): %s", folderName)
	}

	filterName = matches[1]
	date = matches[2]

	return filterName, date, nil
}

// ValidateWAVPNGPairs checks that each WAV file has a corresponding PNG file
// Returns lists of properly paired base names and mismatched files
func ValidateWAVPNGPairs(wavFiles, pngFiles []string) (paired []string, mismatched []string) {
	// Create a map of PNG base names for quick lookup
	pngMap := make(map[string]bool)
	for _, pngFile := range pngFiles {
		baseName := strings.TrimSuffix(pngFile, filepath.Ext(pngFile))
		pngMap[baseName] = true
	}

	// Check each WAV file
	for _, wavFile := range wavFiles {
		baseName := strings.TrimSuffix(wavFile, filepath.Ext(wavFile))
		if pngMap[baseName] {
			paired = append(paired, baseName)
		} else {
			mismatched = append(mismatched, wavFile)
		}
	}

	return paired, mismatched
}

// ExtractDateTimePattern extracts the date_time pattern from a filename
// Looks for patterns: YYYYMMDD_HHMMSS (8 digits) or YYMMDD_HHMMSS/DDMMYY_HHMMSS (6 digits)
// Returns the pattern and whether it was found
// Example: "A05-20250517_214501" -> ("20250517_214501", true)
func ExtractDateTimePattern(filename string) (pattern string, found bool) {
	// Pattern: 8 digits + underscore + 6 digits (YYYYMMDD_HHMMSS)
	pattern8 := regexp.MustCompile(`(\d{8}_\d{6})`)
	if match := pattern8.FindString(filename); match != "" {
		return match, true
	}

	// Pattern: 6 digits + underscore + 6 digits (YYMMDD_HHMMSS or DDMMYY_HHMMSS)
	pattern6 := regexp.MustCompile(`(\d{6}_\d{6})`)
	if match := pattern6.FindString(filename); match != "" {
		return match, true
	}

	return "", false
}