package model

import (
	"fmt"
	"strconv"
	"strings"
	"time"
)

func parseJumpTarget(raw string) (time.Duration, error) {
	s := strings.TrimSpace(raw)
	if s == "" {
		return 0, fmt.Errorf("use ss, mm:ss, or hh:mm:ss format")
	}

	parts := strings.Split(s, ":")
	switch len(parts) {
	case 1:
		secs, err := parseTotalSeconds(parts[0])
		if err != nil {
			return 0, err
		}
		return time.Duration(secs) * time.Second, nil
	case 2:
		minPart := normalizeClockField(parts[0])
		secPart := normalizeClockField(parts[1])

		mins, err := parseTotalMinutes(minPart)
		if err != nil {
			return 0, err
		}
		secs, err := parseClockSeconds(secPart)
		if err != nil {
			return 0, err
		}
		return time.Duration(mins)*time.Minute + time.Duration(secs)*time.Second, nil
	case 3:
		hourPart := normalizeClockField(parts[0])
		minPart := normalizeClockField(parts[1])
		secPart := normalizeClockField(parts[2])

		hours, err := parseTotalHours(hourPart)
		if err != nil {
			return 0, err
		}
		mins, err := parseClockMinutes(minPart)
		if err != nil {
			return 0, err
		}
		secs, err := parseClockSeconds(secPart)
		if err != nil {
			return 0, err
		}
		return time.Duration(hours)*time.Hour +
			time.Duration(mins)*time.Minute +
			time.Duration(secs)*time.Second, nil
	default:
		return 0, fmt.Errorf("use ss, mm:ss, or hh:mm:ss format")
	}
}

func normalizeClockField(s string) string {
	s = strings.TrimSpace(s)
	if s == "" {
		return "0"
	}
	return s
}

func parseTotalSeconds(s string) (int, error) {
	secs, err := parseNonNegativeInt(strings.TrimSpace(s), "seconds")
	if err != nil {
		return 0, err
	}
	return secs, nil
}

func parseTotalMinutes(s string) (int, error) {
	mins, err := parseNonNegativeInt(s, "minutes")
	if err != nil {
		return 0, err
	}
	return mins, nil
}

func parseTotalHours(s string) (int, error) {
	hours, err := parseNonNegativeInt(s, "hours")
	if err != nil {
		return 0, err
	}
	return hours, nil
}

func parseClockMinutes(s string) (int, error) {
	if len(s) > 2 {
		return 0, fmt.Errorf("minutes must be 0-59")
	}

	mins, err := parseNonNegativeInt(s, "minutes")
	if err != nil {
		return 0, err
	}
	if mins > 59 {
		return 0, fmt.Errorf("minutes must be 0-59")
	}
	return mins, nil
}

func parseClockSeconds(s string) (int, error) {
	if len(s) > 2 {
		return 0, fmt.Errorf("seconds must be 0-59")
	}

	secs, err := parseNonNegativeInt(s, "seconds")
	if err != nil {
		return 0, err
	}
	if secs > 59 {
		return 0, fmt.Errorf("seconds must be 0-59")
	}
	return secs, nil
}

func parseNonNegativeInt(s, label string) (int, error) {
	if s == "" {
		return 0, fmt.Errorf("%s must be a number", label)
	}
	for _, r := range s {
		if r < '0' || r > '9' {
			return 0, fmt.Errorf("%s must be a number", label)
		}
	}
	v, err := strconv.Atoi(s)
	if err != nil {
		return 0, fmt.Errorf("%s must be a number", label)
	}
	return v, nil
}

func formatJumpClock(d time.Duration) string {
	if d < 0 {
		d = 0
	}
	total := int(d.Seconds())
	mm := total / 60
	ss := total % 60
	return fmt.Sprintf("%02d:%02d", mm, ss)
}

func formatJumpPlaceholder(d time.Duration) string {
	return "00:00"
}
