//
//  BroadcastView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 01/05/2024.
//

import SwiftUI
import CoreImage.CIFilterBuiltins
import LeStorage
import TipKit

extension String : Identifiable {
    public var id: String { self }
}

struct BroadcastView: View {
    @EnvironmentObject var dataStore: DataStore
    @Environment(Tournament.self) var tournament: Tournament
    @Environment(NavigationViewModel.self) var navigation: NavigationViewModel

    let context = CIContext()
    let filter = CIFilter.qrCodeGenerator()
    @State private var urlToShow: String?
    @State private var tvMode: Bool = false
    @State private var pageLink: PageLink = .teams
    
    let createAccountTip = CreateAccountTip()
    let tournamentPublishingTip = TournamentPublishingTip()
    let tournamentTVBroadcastTip = TournamentTVBroadcastTip()
    
    var body: some View {
        @Bindable var tournament = tournament
        List {
            if Store.main.userId == nil {
                Section {
                    TipView(createAccountTip) { action in
                        switch action.id {
                        case CreateAccountTip.ActionKey.accessPadelClubWebPage.rawValue:
                            UIApplication.shared.open(URLs.main.url)
                        case CreateAccountTip.ActionKey.createAccount.rawValue:
                            navigation.selectedTab = .umpire
                        default:
                            break
                            //todo
//                        case CreateAccountTip.ActionKey.learnMore.rawValue:
//                            UIApplication.shared.open(URLs.padelClubLandingPage.url)
                        }
                    }
                    .tipStyle(tint: .master)
                }
            }
            
            Section {
                TipView(tournamentPublishingTip) { action in
                    UIApplication.shared.open(URLs.main.url)
                }
                .tipStyle(tint: nil)
            }
            Section {
                TipView(tournamentTVBroadcastTip)
                    .tipStyle(tint: nil)
            }

            if tournament.isPrivate == false {
                if let url = tournament.shareURL(.clubBroadcast) {
                    Section {
                        Link(destination: url) {
                            Text(url.absoluteString)
                        }
                        .contextMenu {
                            Button("Copier") {
                                let pasteboard = UIPasteboard.general
                                pasteboard.string = url.absoluteString
                            }
                        }
                    } header: {
                        Text("Lien pour la diffusion TV")
                    } footer: {
                        Text("Lien à mettre sur une smart tv ou ordinateur dans le club house par exemple !")
                    }
                }
            
                
                Section {
                    LabeledContent {
                        if tournament.isTournamentPublished() {
                            Image(systemName:"checkmark").foregroundStyle(.green)
                        } else {
                            Text(tournament.publishedTournamentDate().formatted())
                        }
                    } label: {
                        if tournament.isTournamentPublished() {
                            Text("Publiée")
                        } else {
                            Text("Publication prévue")
                        }
                    }
                    
                    if tournament.canBePublished() == false {
                        Text("Pour être visible automatiquement, le tournoi doit avoir été créé il y a 24h, avoir une structure et au moins 4 inscriptions.")
                    }
                } header: {
                    Text("Information sur le tournoi")
                } footer: {
                    if Date() < tournament.publishedTournamentDate() || tournament.canBePublished() == false {
                        HStack {
                            Spacer()
                            FooterButtonView(tournament.publishTournament ? "masquer sur le site" : "publier maintenant") {
                                tournament.publishTournament.toggle()
                                _save()
                            }
                        }
                    }
                }

                Section {
                    LabeledContent {
                        if tournament.areTeamsPublished() {
                            Image(systemName:"checkmark").foregroundStyle(.green)
                        } else {
                            Text(tournament.publishedTeamsDate().formatted())
                        }
                    } label: {
                        if tournament.areTeamsPublished() {
                            Text("Publiée")
                        } else {
                            Text("Publication prévue")
                        }
                    }
                    
                    Toggle(isOn: $tournament.hideTeamsWeight) {
                        Text("Masquer les poids des équipes")
                    }
                } header: {
                    Text("Liste des équipes")
                } footer: {
                    if Date() < tournament.publishedTeamsDate() {
                        HStack {
                            Spacer()
                            FooterButtonView(tournament.publishTeams ? "masquer sur le site" : "publier maintenant") {
                                tournament.publishTeams.toggle()
                                _save()
                            }
                        }
                    }
                }
                
                Section {
                    LabeledContent {
                        if tournament.areSummonsPublished() {
                            Image(systemName:"checkmark").foregroundStyle(.green)
                        } else {
                            Text(tournament.publishedTeamsDate().formatted())
                        }
                    } label: {
                        if tournament.areSummonsPublished() {
                            Text("Publiées")
                        } else {
                            Text("Publication prévue")
                        }
                    }
                } header: {
                    Text("Convocations")
                } footer: {
                    if Date() < tournament.publishedTeamsDate() {
                        HStack {
                            Spacer()
                            FooterButtonView(tournament.publishSummons ? "masquer sur le site" : "publier maintenant") {
                                tournament.publishSummons.toggle()
                                _save()
                            }
                        }
                    }
                }
                
                if let publishedGroupStagesDate = tournament.publishedGroupStagesDate() {
                    Section {
                        let areGroupStagesPublished = tournament.areGroupStagesPublished()
                        LabeledContent {
                            if areGroupStagesPublished {
                                Image(systemName:"checkmark").foregroundStyle(.green)
                            } else {
                                Text(publishedGroupStagesDate.formatted())
                            }
                        } label: {
                            if areGroupStagesPublished {
                                Text("Publiées")
                            } else {
                                Text("Publication prévue")
                            }
                        }
                    } header: {
                        Text("Poules")
                    } footer: {
                        if Date() < publishedGroupStagesDate {
                            HStack {
                                Spacer()
                                FooterButtonView(tournament.publishGroupStages ? "masquer sur le site" : "publier maintenant") {
                                    tournament.publishGroupStages.toggle()
                                    _save()
                                }
                            }
                        }
                    }
                }
                
                if let publishedBracketsDate = tournament.publishedBracketsDate() {
                    Section {
                        let areBracketsPublished = tournament.areBracketsPublished()
                        LabeledContent {
                            if areBracketsPublished {
                                Image(systemName:"checkmark").foregroundStyle(.green)
                            } else {
                                Text(publishedBracketsDate.formatted())
                            }
                        } label: {
                            if areBracketsPublished {
                                Text("Publié")
                            } else {
                                Text("Publication prévue")
                            }
                        }
                    } header: {
                        Text("Tableau")
                    } footer: {
                        if Date() < publishedBracketsDate {
                            HStack {
                                Spacer()
                                FooterButtonView(tournament.publishBrackets ? "masquer sur le site" : "publier maintenant") {
                                    tournament.publishBrackets.toggle()
                                    _save()
                                }
                            }
                        }
                    }
                }
            }
            
            //todo waitinglist & info
                        
            Section {
                Toggle(isOn: $tournament.isPrivate) {
                    Text("Tournoi privé")
                }
            } footer: {
                let footerString = "Le tournoi sera masqué sur le site [Padel Club](\(URLs.main.rawValue))"
                Text(.init(footerString))
            }
            
            Section {
                LabeledContent {
                    actionForURL(URLs.main.url)
                } label: {
                    Text("Padel Club")
                }

                let club = tournament.club()
                LabeledContent {
                    if let clubURL = club?.shareURL() {
                        actionForURL(clubURL)
                    }
                } label: {
                    Text("Club")
                    if let club {
                        Text(club.clubTitle())
                    } else {
                        Text("Aucun club indiqué pour ce tournoi")
                    }
                }

                if let url = tournament.shareURL(pageLink) {
                    LabeledContent {
                        actionForURL(url)
                    } label: {
                        Text("Tournoi")
                        Text(pageLink.localizedLabel())
                    }
                }
                
                let links : [PageLink] = [.teams, .summons, .groupStages, .matches, .rankings, .broadcast, .clubBroadcast]
                Picker(selection: $pageLink) {
                    ForEach(links) { pageLink in
                        Text(pageLink.localizedLabel()).tag(pageLink)
                    }
                } label: {
                    Text("Modifier la page du tournoi à partager")
                }
                .pickerStyle(.menu)
            } header: {
                Text("Liens à partager")
                    .textCase(nil)
            }

        }
        .headerProminence(.increased)
        .navigationTitle("Publication")
        .navigationBarTitleDisplayMode(.inline)
        .toolbarBackground(.visible, for: .navigationBar)
        .sheet(item: $urlToShow) { urlToShow in
            Image(uiImage: generateQRCode(from: urlToShow))
                .interpolation(.none)
                .resizable()
                .scaledToFit()
                .frame(width: 300, height: 300)
                .onAppear {
                    UIPasteboard.general.string = urlToShow
                }
        }
        .onChange(of: [tournament.hideTeamsWeight, tournament.isPrivate]) {
            _save()
        }
    }
    
    private func _save() {
        do {
            if [tournament.publishTeams, tournament.publishSummons, tournament.publishBrackets, tournament.publishGroupStages].anySatisfy({ $0 == true }) {
                tournament.publishTournament = true
            }
            
            if tournament.publishTournament == false {
                tournament.publishTeams = false
                tournament.publishSummons = false
                tournament.publishBrackets = false
                tournament.publishGroupStages = false
            }
            try dataStore.tournaments.addOrUpdate(instance: tournament)
        } catch {
            Logger.error(error)
        }
    }
    
    private func generateQRCode(from string: String) -> UIImage {
        filter.message = Data(string.utf8)

        if let outputImage = filter.outputImage {
            if let cgimg = context.createCGImage(outputImage, from: outputImage.extent) {
                return UIImage(cgImage: cgimg)
            }
        }

        return UIImage(systemName: "xmark.circle") ?? UIImage()
    }

    @ViewBuilder
    func actionForURL(_ url: URL, removeSource: Bool = false) -> some View {
        Menu {
            Button {
                UIApplication.shared.open(url)
            } label: {
                Label("Voir", systemImage: "safari")
            }
            
            Button {
                urlToShow = url.absoluteString
            } label: {
                Label("QRCode", systemImage: "qrcode")
            }
            
            ShareLink(item: url) {
                Label("Partager le lien", systemImage: "link")
            }
        } label: {
            HStack {
                Spacer()
                Image(systemName: "square.and.arrow.up")
            }
        }
        .frame(maxWidth: .infinity)
        .buttonStyle(.borderless)
    }
    

}

//#Preview {
//    BroadcastView()
//}
