//
//  AuditionRoleDetailView.swift
//  SodaLive
//
//  Created by klaus on 1/6/25.
//

import SwiftUI
import Kingfisher

struct AuditionRoleDetailView: View {
    
    let roleId: Int
    let auditionTitle: String
    
    @StateObject var viewModel = AuditionRoleDetailViewModel()
    @StateObject var keyboardHandler = KeyboardHandler()
    @StateObject var soundManager = AuditionSoundManager.shared
    
    @State private var isShowApplyMethodView = false
    @State private var isShowSelectAudioView = false
    @State private var isShowRecordingView = false
    @State private var isShowNoticeAuthView = false
    @State private var isShowApplyView = false
    @State private var isShowNoticeReapply = false
    @State private var isShowApplyCompleteView = false
    
    var body: some View {
        BaseView(isLoading: $viewModel.isLoading) {
            ZStack(alignment: .bottomTrailing) {
                VStack(spacing: 0) {
                    DetailNavigationBar(title: viewModel.name)
                    
                    ScrollView(.vertical, showsIndicators: false) {
                        LazyVStack(spacing: 15) {
                            if let roleDetail = viewModel.auditionRoleDetail {
                                KFImage(URL(string: roleDetail.imageUrl))
                                    .cancelOnDisappear(true)
                                    .downsampling(size: CGSize(width: 1000, height: 350))
                                    .resizable()
                                    .aspectRatio(1000/350, contentMode: .fit)
                                    .frame(maxWidth: .infinity)
                                    .cornerRadius(6.7)
                                    .padding(.top, 3)
                                
                                HStack(spacing: 14) {
                                    if let url = URL(string: roleDetail.originalWorkUrl), UIApplication.shared.canOpenURL(url) {
                                        Text("원작 보러가기")
                                            .font(.custom(Font.bold.rawValue, size: 16))
                                            .foregroundColor(Color.button)
                                            .padding(.vertical, 12)
                                            .frame(maxWidth: .infinity)
                                            .overlay(
                                                RoundedRectangle(cornerRadius: 10)
                                                    .stroke(Color.button, lineWidth: 1)
                                            )
                                            .contentShape(Rectangle())
                                            .onTapGesture { UIApplication.shared.open(url) }
                                    }
                                    
                                    if let url = URL(string: roleDetail.auditionScriptUrl), UIApplication.shared.canOpenURL(url) {
                                        Text("오디션 대본 확인")
                                            .font(.custom(Font.bold.rawValue, size: 16))
                                            .foregroundColor(Color.button)
                                            .padding(.vertical, 12)
                                            .frame(maxWidth: .infinity)
                                            .overlay(
                                                RoundedRectangle(cornerRadius: 10)
                                                    .stroke(Color.button, lineWidth: 1)
                                            )
                                            .contentShape(Rectangle())
                                            .onTapGesture { UIApplication.shared.open(url) }
                                    }
                                }
                                
                                VStack(alignment: .leading, spacing: 13.3) {
                                    Text("오디션 캐릭터 정보")
                                        .font(.custom(Font.bold.rawValue, size: 14.7))
                                        .foregroundColor(Color.grayee)
                                    
                                    ExpandableTextView(text: roleDetail.information)
                                }
                            }
                            
                            if viewModel.applicantList.isEmpty {
                                Text("지원자가 없습니다.")
                                    .font(.custom(Font.medium.rawValue, size: 13))
                                    .foregroundColor(Color.grayee)
                                    .padding(.top, 15)
                            } else {
                                HStack(spacing: 0) {
                                    Text("참여자")
                                        .font(.custom(Font.medium.rawValue, size: 13.3))
                                        .foregroundColor(Color.graybb)
                                    
                                    Text("\(viewModel.totalCount)")
                                        .font(.custom(Font.medium.rawValue, size: 13.3))
                                        .foregroundColor(Color.button)
                                        .padding(.leading, 2.3)
                                    
                                    Text("명")
                                        .font(.custom(Font.medium.rawValue, size: 13.3))
                                        .foregroundColor(Color.graybb)
                                    
                                    Spacer()
                                    
                                    Text("최신순")
                                        .font(.custom(Font.medium.rawValue, size: 13.3))
                                        .foregroundColor(
                                            viewModel.sortType == .NEWEST ? Color.button : Color.graybb
                                        )
                                        .onTapGesture {
                                            viewModel.setSortType(sortType: .NEWEST)
                                        }
                                    
                                    Text("좋아요순")
                                        .font(.custom(Font.medium.rawValue, size: 13.3))
                                        .foregroundColor(
                                            viewModel.sortType == .LIKES ? Color.button : Color.graybb
                                        )
                                        .onTapGesture {
                                            viewModel.setSortType(sortType: .LIKES)
                                        }
                                        .padding(.leading, 13.3)
                                }
                                .padding(.top, 15)
                                
                                VStack(spacing: 5.3) {
                                    ForEach(0..<viewModel.applicantList.count, id: \.self) {
                                        let applicant = viewModel.applicantList[$0]
                                        
                                        AuditionApplicantItemView(
                                            item: applicant,
                                            onClickVote: {
                                                viewModel.voteApplicant(applicantId: $0)
                                            }
                                        ).padding(.bottom, $0 == viewModel.applicantList.count - 1 ? 33 : 0)
                                        
                                        if $0 == viewModel.applicantList.count - 1 {
                                            Color.clear
                                                .frame(height: 0)
                                                .onAppear {
                                                    viewModel.getAuditionApplicantList()
                                                }
                                        }
                                    }
                                }
                            }
                        }
                        .padding(.horizontal, 13.3)
                    }
                }
                .popup(isPresented: $viewModel.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) {
                    HStack {
                        Spacer()
                        Text(viewModel.errorMessage)
                            .padding(.vertical, 13.3)
                            .frame(width: screenSize().width - 66.7, alignment: .center)
                            .font(.custom(Font.medium.rawValue, size: 12))
                            .background(Color.button)
                            .foregroundColor(Color.white)
                            .multilineTextAlignment(.leading)
                            .cornerRadius(20)
                            .padding(.bottom, 66.7)
                        Spacer()
                    }
                }
                .popup(isPresented: $soundManager.isShowPopup, type: .toast, position: .bottom, autohideIn: 2) {
                    HStack {
                        Spacer()
                        Text(soundManager.errorMessage)
                            .padding(.vertical, 13.3)
                            .frame(width: screenSize().width - 66.7, alignment: .center)
                            .font(.custom(Font.medium.rawValue, size: 12))
                            .background(Color.button)
                            .foregroundColor(Color.white)
                            .multilineTextAlignment(.leading)
                            .cornerRadius(20)
                            .padding(.bottom, 66.7)
                        Spacer()
                    }
                }
                .onAppear {
                    viewModel.onFailure = { AppState.shared.back() }
                    viewModel.auditionRoleId = roleId
                }
                .onDisappear {
                    soundManager.resetPlayer()
                }
                
                if let roleDetail = viewModel.auditionRoleDetail {
                    Text(roleDetail.isAlreadyApplicant ? "오디션 재지원" : "오디션 지원")
                        .font(.custom(Font.bold.rawValue, size: 15.3))
                        .foregroundColor(Color.white)
                        .padding(14)
                        .background(Color.button)
                        .cornerRadius(44)
                        .padding(.trailing, 19)
                        .padding(.bottom, 19)
                        .onTapGesture {
                            if UserDefaults.bool(forKey: .auth) {
                                if viewModel.isShowNoticeReapply {
                                    isShowNoticeReapply = true
                                } else {
                                    isShowApplyMethodView = true
                                }
                            } else {
                                isShowNoticeAuthView = true
                            }
                        }
                }
            }
            .fileImporter(
                isPresented: $isShowSelectAudioView,
                allowedContentTypes: [.audio],
                allowsMultipleSelection: false
            ) { result in
                handleFileImport(result: result)
            }
            
            if isShowApplyMethodView {
                ApplyMethodView(
                    isShowing: $isShowApplyMethodView,
                    onClickSelectAudioFile: {
                        isShowApplyMethodView = false
                        isShowSelectAudioView = true
                    },
                    onClickRecording: {
                        isShowApplyMethodView = false
                        isShowRecordingView = true
                    }
                )
            }
            
            if isShowRecordingView {
                AuditionApplicantRecordingView(
                    isShowing: $isShowRecordingView,
                    isShowPopup: $viewModel.isShowPopup,
                    errorMessage: $viewModel.errorMessage,
                    onClickCompleteRecording: { fileName, soundData in
                        viewModel.fileName = fileName
                        viewModel.soundData = soundData
                        isShowRecordingView = false
                        isShowApplyView = true
                    }
                )
            }
            
            if isShowApplyView {
                AuditionApplyView(
                    isShowing: $isShowApplyView,
                    phoneNumber: $viewModel.phoneNumber,
                    filename: viewModel.fileName,
                    onClickApply: {
                        viewModel.applyAudition {
                            isShowApplyView = false
                            isShowRecordingView = false
                            isShowApplyCompleteView = true
                        }
                    }
                )
                .offset(y: 0 - (keyboardHandler.keyboardHeight / 10))
                .onDisappear {
                    viewModel.soundData = nil
                    viewModel.fileName = ""
                    viewModel.deleteAllRecordingFilesWithNamePrefix("voiceon_now_voice")
                }
            }
            
            if isShowNoticeReapply {
                SodaDialog(
                    title: "재지원 안내",
                    desc: "재지원 시 이전 지원 내역은 삭제되며 받은 투표수는 무효 처리됩니다.",
                    confirmButtonTitle: "확인"
                ) {
                    isShowNoticeReapply = false
                    isShowApplyMethodView = true
                }
            }
            
            if isShowNoticeAuthView {
                SodaDialog(
                    title: "- 본인인증 -",
                    desc: "마이페이지에서 '본인인증'을 하고 다시 오디션에 지원해 주세요.",
                    confirmButtonTitle: "확인"
                ) {
                    isShowNoticeAuthView = false
                }
            }
            
            if viewModel.isShowVoteCompleteView {
                SodaDialog(
                    title: viewModel.dialogTitle,
                    desc: viewModel.dialogDesc,
                    confirmButtonTitle: "확인"
                ) {
                    viewModel.isShowVoteCompleteView = false
                    viewModel.isShowNotifyVote = false
                }
            }
            
            if isShowApplyCompleteView {
                ApplyAuditionCompleteDialog(
                    auditionTitle: auditionTitle,
                    roleName: viewModel.name,
                    isShowing: $isShowApplyCompleteView
                )
            }
            
            if soundManager.isLoading {
                LoadingView()
            }
        }
    }
    
    private func handleFileImport(result: Result<[URL], Error>) {
        switch result {
        case .success(let url):
            let fileUrl = url[0]
            
            if fileUrl.startAccessingSecurityScopedResource() {
                defer {
                    fileUrl.stopAccessingSecurityScopedResource()
                }
                
                if let data = try? Data(contentsOf: fileUrl) {
                    viewModel.soundData = data
                    viewModel.fileName = fileUrl.lastPathComponent
                    isShowApplyView = true
                } else {
                    viewModel.errorMessage = "콘텐츠 파일을 불러오지 못했습니다.\n다시 선택해 주세요"
                    viewModel.isShowPopup = true
                }
            } else {
                viewModel.errorMessage = "콘텐츠 파일을 불러오지 못했습니다.\n다시 선택해 주세요"
                viewModel.isShowPopup = true
            }
            
        case .failure(let error):
            DEBUG_LOG("error: \(error.localizedDescription)")
            viewModel.errorMessage = "콘텐츠 파일을 불러오지 못했습니다.\n다시 선택해 주세요"
            viewModel.isShowPopup = true
        }
    }
}

#Preview {
    AuditionRoleDetailView(roleId: 1, auditionTitle: "스위치온")
}