//
//  SetInputView.swift
//  PadelClub
//
//  Created by Razmig Sarkissian on 02/04/2024.
//

import SwiftUI

struct SetInputView: View {
    @Binding var setDescriptor: SetDescriptor
    @State private var showSetInputView: Bool = true
    @State private var showTieBreakInputView: Bool = false
    var firstTeamIsFirstScoreToEnter: Bool = true

    var setFormat: SetFormat { setDescriptor.setFormat }
    
    private var showTieBreakView: Bool {
        setDescriptor.shouldTieBreak
    }
    
    private var isMainViewTieBreakView: Bool {
        setFormat == .superTieBreak || setFormat == .megaTieBreak
    }
    
    var defaultTeamValue: Int? {
        if firstTeamIsFirstScoreToEnter {
            return setDescriptor.valueTeamOne
        } else {
            return setDescriptor.valueTeamTwo
        }
    }
    
    var defaultTeamValueBinding: Binding<Int?> {
        Binding {
            defaultTeamValue
        } set: { value in
            if firstTeamIsFirstScoreToEnter {
                setDescriptor.valueTeamOne = value
            } else {
                setDescriptor.valueTeamTwo = value
            }
        }
    }
    
    var otherTeamValue: Int? {
        if firstTeamIsFirstScoreToEnter {
            return setDescriptor.valueTeamTwo
        } else {
            return setDescriptor.valueTeamOne
        }
    }
    
    var otherTeamValueBinding: Binding<Int?> {
        Binding {
            otherTeamValue
        } set: { value in
            if firstTeamIsFirstScoreToEnter {
                setDescriptor.valueTeamTwo = value
            } else {
                setDescriptor.valueTeamOne = value
            }
        }

    }
    
    var defaultTeamTieBreakValue: Int? {
        if firstTeamIsFirstScoreToEnter {
            return setDescriptor.tieBreakValueTeamOne
        } else {
            return setDescriptor.tieBreakValueTeamTwo
        }
    }
    
    var defaultTeamTieBreakValueBinding: Binding<Int?> {
        Binding {
            defaultTeamTieBreakValue
        } set: { value in
            if firstTeamIsFirstScoreToEnter {
                setDescriptor.tieBreakValueTeamOne = value
            } else {
                setDescriptor.tieBreakValueTeamTwo = value
            }
        }
    }
    
    var otherTeamTieBreakValue: Int? {
        if firstTeamIsFirstScoreToEnter {
            return setDescriptor.tieBreakValueTeamTwo
        } else {
            return setDescriptor.tieBreakValueTeamOne
        }
    }
    
    var otherTeamTieBreakValueBinding: Binding<Int?> {
        Binding {
            otherTeamTieBreakValue
        } set: { value in
            if firstTeamIsFirstScoreToEnter {
                setDescriptor.tieBreakValueTeamTwo = value
            } else {
                setDescriptor.tieBreakValueTeamOne = value
            }
        }

    }

    private var currentValue: Binding<Int?> {
        Binding {
            if defaultTeamValue != nil {
                return otherTeamValue
            } else {
                return defaultTeamValue
            }
        } set: { newValue, _ in
            if defaultTeamValue != nil {
                otherTeamValueBinding.wrappedValue = newValue
            } else {
                defaultTeamValueBinding.wrappedValue = newValue
            }
        }
    }

    private var currentTiebreakValue: Binding<Int?> {
        Binding {
            if defaultTeamTieBreakValue != nil {
                return otherTeamTieBreakValue
            } else {
                return defaultTeamTieBreakValue
            }
        } set: { newValue, _ in
            
            if let tieBreakValueTeamOne = defaultTeamTieBreakValue, let tieBreakValueTeamTwo = otherTeamTieBreakValue {
                if tieBreakValueTeamOne < tieBreakValueTeamTwo && tieBreakValueTeamTwo > 6 {
                    defaultTeamTieBreakValueBinding.wrappedValue = newValue
                }
                else if tieBreakValueTeamOne > tieBreakValueTeamTwo && tieBreakValueTeamOne > 6 {
                    otherTeamTieBreakValueBinding.wrappedValue = newValue
                }
            }
            else if defaultTeamTieBreakValue != nil {
                otherTeamTieBreakValueBinding.wrappedValue = newValue
            } else {
                defaultTeamTieBreakValueBinding.wrappedValue = newValue
            }
        }
    }
    
    private var disableValues: [Int] {
        if let valueTeamOne = defaultTeamValue {
            return setFormat.disableValuesForTeamTwo(with: valueTeamOne)
        }
        return []
    }
    
    private var disableTieBreakValues: [Int] {
        if let tieBreakValueTeamOne = defaultTeamTieBreakValue {
            if tieBreakValueTeamOne == 7 {
                return [7,6]
            }
        }
        return []
    }
    
    func deleteLastValue() {
        setDescriptor.valueTeamOne = nil
        setDescriptor.valueTeamTwo = nil
    }
    
    func deleteLastTiebreakValue() {
        setDescriptor.tieBreakValueTeamOne = nil
        setDescriptor.tieBreakValueTeamTwo = nil
    }
    
    func possibleValues() -> [Int] {
        if let valueTeamOne = defaultTeamValue {
            if valueTeamOne == 7 && setFormat == .six {
                return [6,5]
            }
            if valueTeamOne == 5 && setFormat == .four {
                return [4,3]
            }
        }
        return setFormat.possibleValues
    }
    
    func tieBreakPossibleValues() -> [Int] {
        if let tieBreakValueTeamOne = defaultTeamTieBreakValue, let tieBreakValueTeamTwo = otherTeamTieBreakValue {
            if tieBreakValueTeamOne == 6 && tieBreakValueTeamTwo == 8 {
                return []
            }
            if tieBreakValueTeamOne < 7 && tieBreakValueTeamTwo == 7 {
                return [9, 5, 4, 3, 2, 1, 0]
            }
            if tieBreakValueTeamOne == 7 && tieBreakValueTeamTwo < 7 {
                return [9, 5, 4, 3, 2, 1, 0]
            }
            return Array(((max(tieBreakValueTeamOne, tieBreakValueTeamTwo)+2)..<max(tieBreakValueTeamOne, tieBreakValueTeamTwo)+8)).reversed()
        }
        if defaultTeamTieBreakValue != nil {
            return [9, 5, 4, 3, 2, 1, 0]
        }
        return SetFormat.six.possibleValues
    }
    
    var body: some View {
        Section {
            DisclosureGroup(isExpanded: $showSetInputView) {
                PointSelectionView(valueSelected: currentValue, values: possibleValues(), possibleValues: setFormat.possibleValues, disableValues: disableValues, deleteAction: deleteLastValue)
                    .listRowInsets(EdgeInsets(top: -8, leading: -20, bottom: 0, trailing: 0))
            } label: {
                SetLabelView(initialValueLeft: defaultTeamValueBinding, initialValueRight: otherTeamValueBinding, shouldDisplaySteppers: isMainViewTieBreakView)
            }
            if showTieBreakView {
                DisclosureGroup(isExpanded: $showTieBreakInputView) {
                    PointSelectionView(valueSelected: currentTiebreakValue, values: tieBreakPossibleValues(), possibleValues: SetFormat.six.possibleValues, disableValues: disableTieBreakValues, deleteAction: deleteLastTiebreakValue)
                        .listRowInsets(EdgeInsets(top: -8, leading: -20, bottom: 0, trailing: 0))
                } label: {
                    SetLabelView(initialValueLeft: defaultTeamTieBreakValueBinding, initialValueRight: otherTeamTieBreakValueBinding, shouldDisplaySteppers: showTieBreakInputView, isTieBreak: true)
                }
            }
        }
        .onChange(of: showSetInputView) {
            setDescriptor.showSetInputView = showSetInputView
        }
        .onChange(of: showTieBreakInputView) {
            setDescriptor.showTieBreakInputView = showTieBreakInputView
        }
        .onChange(of: defaultTeamValue) {
            if let newValue = defaultTeamValue {
                if newValue == setFormat.scoreToWin - 1 && setFormat.tieBreak == 8 {
                    otherTeamValueBinding.wrappedValue = setFormat.scoreToWin
                } else if newValue == setFormat.scoreToWin - 2 && setFormat.tieBreak == 8 {
                    otherTeamValueBinding.wrappedValue = setFormat.scoreToWin
                } else if newValue == setFormat.scoreToWin - 1 {
                    otherTeamValueBinding.wrappedValue = setFormat.scoreToWin + 1
                } else if newValue <= setFormat.scoreToWin - 2 {
                    otherTeamValueBinding.wrappedValue = setFormat.scoreToWin
                } else if newValue > 10 && setFormat == .superTieBreak {
                    otherTeamValueBinding.wrappedValue = newValue - 2
                } else if newValue > 15 && setFormat == .megaTieBreak {
                    otherTeamValueBinding.wrappedValue = newValue - 2
                }

            }
        }
        .onChange(of: otherTeamValue) {
            if defaultTeamValue != nil && otherTeamValue != nil {
                showSetInputView = false
            }
        }
        .onChange(of: defaultTeamTieBreakValue) {
            if let newValue = defaultTeamTieBreakValue, otherTeamTieBreakValue == nil {
                if newValue > 7 {
                    otherTeamTieBreakValueBinding.wrappedValue = newValue - 2
                }
                if newValue == 6 {
                    otherTeamTieBreakValueBinding.wrappedValue = newValue + 2
                }
                if newValue <= 5 {
                    otherTeamTieBreakValueBinding.wrappedValue = 7
                }
            }
            else if let newValue = defaultTeamTieBreakValue, let tieBreakValueTeamTwo = otherTeamTieBreakValue {
                if newValue > 6 && tieBreakValueTeamTwo < newValue {
                    otherTeamTieBreakValueBinding.wrappedValue = newValue - 2
                }
                if newValue > 6 && tieBreakValueTeamTwo > newValue {
                    otherTeamTieBreakValueBinding.wrappedValue = newValue + 2
                }
                if newValue == 6 {
                    otherTeamTieBreakValueBinding.wrappedValue = newValue + 2
                }
                if newValue <= 5 {
                    otherTeamTieBreakValueBinding.wrappedValue = 7
                    showTieBreakInputView = false
                }
            }
        }
        .onChange(of: otherTeamTieBreakValue) {
            if let tieBreakValueTeamOne = defaultTeamTieBreakValue, tieBreakValueTeamOne <= 5 {
                showTieBreakInputView = false
            } else {
                if let tieBreakValueTeamTwo = otherTeamTieBreakValue {
                    if tieBreakValueTeamTwo > 6 && tieBreakValueTeamTwo > defaultTeamTieBreakValue ?? 0 {
                        defaultTeamTieBreakValueBinding.wrappedValue = tieBreakValueTeamTwo - 2
                    }
                    if tieBreakValueTeamTwo > 4 && tieBreakValueTeamTwo < defaultTeamTieBreakValue ?? 0 {
                        defaultTeamTieBreakValueBinding.wrappedValue = tieBreakValueTeamTwo + 2
                    }
                }
                
                if let tieBreakValueTeamTwo = otherTeamTieBreakValue, let tieBreakValueTeamOne = defaultTeamTieBreakValue {
                    if tieBreakValueTeamTwo < 6 && tieBreakValueTeamOne == 7 {
                        showTieBreakInputView = false
                    }
                }

            }
        }
        .listRowSeparator(.hidden)
    }
}
