import SwiftUI

/*
 This displays a resizable tab pill for the current queue position. It only shows a max of 6 clips,
 and only shows when the user is playing newly created songs.
 */
public struct PillPagingIndicator: View {
    let currentIndex: Int
    let totalItems: Int
    let maxVisible: Int
    let color: Color

    public init(currentIndex: Int, totalItems: Int, maxVisible: Int, color: Color = .white) {
        self.currentIndex = currentIndex
        self.totalItems = totalItems
        self.maxVisible = maxVisible
        self.color = color
    }

    public var body: some View {
        HStack(spacing: 4) {
            ForEach(visibleIndices, id: \.self) { index in
                Capsule()
                    .fill(color)
                    .frame(width: getIndicatorWidth(for: index), height: getIndicatorHeight(for: index))
                    .opacity(getIndicatorOpacity(for: index))
            }
        }
        .opacity(totalItems > 1 ? 1 : 0)
        .animation(.easeInOut(duration: 0.3), value: currentIndex)
        .shadow(color: .black.opacity(0.3), radius: 4, x: 0, y: 0)
    }

    private var visibleIndices: [Int] {
        guard totalItems > maxVisible else {
            return Array(0 ..< totalItems)
        }

        let halfVisible = maxVisible / 2
        var startIndex = currentIndex - halfVisible + 1
        var endIndex = currentIndex + halfVisible

        if startIndex < 0 {
            let offset = -startIndex
            startIndex = 0
            endIndex = min(totalItems - 1, endIndex + offset)
        }

        if endIndex >= totalItems {
            let offset = endIndex - (totalItems - 1)
            endIndex = totalItems - 1
            startIndex = max(0, startIndex - offset)
        }

        return Array(startIndex ... endIndex)
    }

    private func getIndicatorWidth(for index: Int) -> CGFloat {
        if index == currentIndex {
            return 30
        }

        let distance = abs(index - currentIndex)
        switch distance {
        case 1: return 12
        case 2: return 10
        case 3: return 8
        default: return 6
        }
    }

    private func getIndicatorHeight(for index: Int) -> CGFloat {
        if index == currentIndex {
            return 12
        }

        let distance = abs(index - currentIndex)
        switch distance {
        case 1: return 12
        case 2: return 10
        case 3: return 8
        default: return 6
        }
    }

    private func getIndicatorOpacity(for index: Int) -> Double {
        let distance = abs(index - currentIndex)
        switch distance {
        case 0: return 1.0
        default: return 0.8
        }
    }
}
