import UIKit

public struct AnimatedLyric: Equatable {
    let text: String
    let start_s: Double
    let end_s: Double

    public init(text: String, start_s: Double, end_s: Double) {
        self.text = text
        self.start_s = start_s
        self.end_s = end_s
    }

    // Pass in `alignedLyrics.map { (word: $0.word, startsAt: $0.startsAt, endsAt: $0.endsAt) }` for `lyrics`
    public static func createFromAlignedLyricsData(_ lyrics: [(word: String, startsAt: Double, endsAt: Double)], maxWidth: CGFloat, font: UIFont) -> [AnimatedLyric] {
        let lines = splitIntoLines(lyrics: lyrics, maxWidth: maxWidth, font: font)

        return lines.map { line in
            AnimatedLyric(
                text: line.text.trimmingCharacters(in: .whitespaces).removingSongSectionKeyword(),
                start_s: line.lyrics.first?.startsAt ?? 0,
                end_s: line.lyrics.last?.endsAt ?? 0
            )
        }
    }

    private static func splitIntoLines(lyrics: [(word: String, startsAt: Double, endsAt: Double)], maxWidth: CGFloat, font: UIFont) -> [(text: String, lyrics: [(word: String, startsAt: Double, endsAt: Double)])] {
        var lines: [(text: String, lyrics: [(word: String, startsAt: Double, endsAt: Double)])] = []
        var currentLine = ""
        var currentLineWidth: CGFloat = 0
        var currentLineLyrics: [(word: String, startsAt: Double, endsAt: Double)] = []

        for lyric in lyrics {
            let word = lyric.word.replacingOccurrences(of: "\n", with: "")
            let wordWithSpace = word + " "
            let wordWidth = (wordWithSpace as NSString).size(withAttributes: [.font: font]).width

            if currentLineWidth + wordWidth > maxWidth {
                if !currentLine.isEmpty {
                    lines.append((text: currentLine.trimmingCharacters(in: .whitespaces), lyrics: currentLineLyrics))
                    currentLine = ""
                    currentLineWidth = 0
                    currentLineLyrics = []
                }
            }

            currentLine += wordWithSpace
            currentLineWidth += wordWidth
            currentLineLyrics.append(lyric)
        }

        if !currentLine.isEmpty {
            lines.append((text: currentLine.trimmingCharacters(in: .whitespaces), lyrics: currentLineLyrics))
        }

        return lines
    }
}
