//
//  ContentDetailPlayView.swift
//  SodaLive
//
//  Created by klaus on 2023/08/13.
//

import SwiftUI
import Kingfisher
import Sliders

struct ContentDetailPlayView: View {
    
    let audioContent: GetAudioContentDetailResponse
    let isAlertPreview: Bool
    @Binding var isShowPreviewAlert: Bool
    
    @StateObject var contentPlayManager = ContentPlayManager.shared
    
    @State private var isRepeat = UserDefaults.bool(forKey: .isContentPlayLoop)
    @State private var isEditing = false
    @State private var progress: TimeInterval = 0
    @State private var timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
    
    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            ZStack {
                KFImage(URL(string: audioContent.coverImageUrl))
                    .cancelOnDisappear(true)
                    .downsampling(
                        size: CGSize(
                            width: screenSize().width - 26.7,
                            height: screenSize().width - 26.7
                        )
                    )
                    .resizable()
                    .scaledToFill()
                    .frame(
                        width: screenSize().width - 26.7,
                        height: screenSize().width - 26.7,
                        alignment: .center
                    )
                    .cornerRadius(10.7, corners: [.topLeft, .topRight])
                
                if let _ = audioContent.totalContentCount, let remainingContentCount = audioContent.remainingContentCount, remainingContentCount <= 0, audioContent.creator.creatorId != UserDefaults.int(forKey: .userId), !audioContent.existOrdered {
                    Text("Sold Out")
                        .font(.custom(Font.bold.rawValue, size: 36.7))
                        .foregroundColor(.white)
                        .frame(
                            width: screenSize().width - 26.7,
                            height: screenSize().width - 26.7,
                            alignment: .center
                        )
                        .background(Color.black.opacity(0.6))
                } else if audioContent.releaseDate == nil && !isAlertPreview || (audioContent.isActivePreview && !audioContent.contentUrl.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty) {
                    Image(isPlaying() ? "btn_audio_content_pause" : isAlertPreview ? "btn_audio_content_preview_play" : "btn_audio_content_play")
                        .onTapGesture {
                            if isPlaying() {
                                contentPlayManager.pauseAudio()
                            } else {
                                contentPlayManager.startTimer = startTimer
                                contentPlayManager.stopTimer = stopTimer
                                
                                contentPlayManager.playAudio(
                                    contentId: audioContent.contentId,
                                    title: audioContent.title,
                                    nickname: audioContent.creator.nickname,
                                    coverImage: audioContent.coverImageUrl,
                                    contentUrl: audioContent.contentUrl,
                                    isFree: audioContent.price <= 0,
                                    isPreview: !audioContent.existOrdered && audioContent.price > 0
                                )
                                isShowPreviewAlert = true
                            }
                        }
                } else if audioContent.releaseDate == nil {
                    Text("해당 콘텐츠는 크리에이터의 요청으로\n미리듣기를 제공하지 않습니다.")
                        .font(.custom(Font.medium.rawValue, size: 16.7))
                        .foregroundColor(Color.grayee)
                        .padding(13.3)
                        .background(Color.gray33.opacity(0.5))
                        .cornerRadius(46.7)
                }
                
                VStack(alignment: .leading, spacing: 13.3) {
                    Spacer()
                    
                    ValueSlider(
                        value: audioContent.contentId == contentPlayManager.contentId ? $progress : .constant(0),
                        in: sliderRange(),
                        onEditingChanged: { editing in
                            isEditing = editing
                            if !editing {
                                contentPlayManager.setCurrentTime(progress)
                            }
                        }
                    )
                    .valueSliderStyle(
                        HorizontalValueSliderStyle(
                            track: HorizontalValueTrack(
                                view: Rectangle().foregroundColor(Color.button),
                                mask: Rectangle()
                            )
                            .background(Rectangle().foregroundColor(Color.gray97.opacity(0.3)))
                            .frame(height: 5.3),
                            thumbSize: CGSizeZero,
                            options: .interactiveTrack
                        )
                    )
                    .frame(height: 5.3)
                }
                
                if contentPlayManager.isLoading {
                    LoadingView()
                }
            }
            .frame(
                width: screenSize().width - 26.7,
                height: screenSize().width - 26.7
            )
            
            HStack(spacing: 0) {
                Text("\(getProgress()) / \(getDuration())")
                    .font(.custom(Font.medium.rawValue, size: 14.7))
                    .foregroundColor(.white)
                
                Spacer()
                
                Image(
                    isRepeat ?
                    "btn_player_repeat" :
                        "btn_player_repeat_done"
                )
                .onTapGesture {
                    isRepeat = !UserDefaults.bool(forKey: .isContentPlayLoop)
                    UserDefaults.set(
                        isRepeat,
                        forKey: .isContentPlayLoop
                    )
                }
            }
            .frame(width: screenSize().width - 40)
        }
        .onAppear {
            if !isPlaying() {
                stopTimer()
            }
        }
        .onReceive(timer) { _ in
            guard let player = contentPlayManager.player, !isEditing else { return }
            self.progress = player.currentTime
        }
    }
    
    private func isPlaying() -> Bool {
        return contentPlayManager.contentId == audioContent.contentId && contentPlayManager.isPlaying
    }
    
    private func sliderRange() -> ClosedRange<Double> {
        if audioContent.contentId == contentPlayManager.contentId {
            return 0...contentPlayManager.duration
        } else {
            return 0...0
        }
    }
    
    private func getProgress() -> String {
        if audioContent.contentId == contentPlayManager.contentId {
            return secondsToMinutesSeconds(seconds: Int(progress))
        } else {
            return secondsToMinutesSeconds(seconds: 0)
        }
    }
    
    private func getDuration() -> String {
        if audioContent.contentId == contentPlayManager.contentId {
            return secondsToMinutesSeconds(seconds: Int(contentPlayManager.duration))
        } else {
            return audioContent.duration
        }
    }
    
    private func secondsToMinutesSeconds(seconds: Int) -> String {
        let hours = String(format: "%02d", seconds / 3600)
        let minute = String(format: "%02d", (seconds % 3600) / 60)
        let second = String(format: "%02d", seconds % 60)
        
        return "\(hours):\(minute):\(second)"
    }
    
    private func startTimer() {
        timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
    }
    
    private func stopTimer() {
        timer.upstream.connect().cancel()
    }
}
