//
//  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 setFormat: SetFormat { setDescriptor.setFormat }
    
    private var showTieBreakView: Bool {
        setFormat.shouldTiebreak(scoreTeamOne: setDescriptor.valueTeamOne ?? 0, scoreTeamTwo: setDescriptor.valueTeamTwo ?? 0)
    }
    
    private var isMainViewTieBreakView: Bool {
        setFormat == .superTieBreak || setFormat == .megaTieBreak
    }
    
    private var currentValue: Binding<Int?> {
        Binding {
            if setDescriptor.valueTeamOne != nil {
                return setDescriptor.valueTeamTwo
            } else {
                return setDescriptor.valueTeamOne
            }
        } set: { newValue, _ in
            if setDescriptor.valueTeamOne != nil {
                setDescriptor.valueTeamTwo = newValue
            } else {
                setDescriptor.valueTeamOne = newValue
            }
        }
    }

    private var currentTiebreakValue: Binding<Int?> {
        Binding {
            if setDescriptor.tieBreakValueTeamOne != nil {
                return setDescriptor.tieBreakValueTeamTwo
            } else {
                return setDescriptor.tieBreakValueTeamOne
            }
        } set: { newValue, _ in
            
            if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne, let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo {
                if tieBreakValueTeamOne < tieBreakValueTeamTwo && tieBreakValueTeamTwo > 6 {
                    setDescriptor.tieBreakValueTeamOne = newValue
                }
                else if tieBreakValueTeamOne > tieBreakValueTeamTwo && tieBreakValueTeamOne > 6 {
                    setDescriptor.tieBreakValueTeamTwo = newValue
                }
            }
            else if setDescriptor.tieBreakValueTeamOne != nil {
                setDescriptor.tieBreakValueTeamTwo = newValue
            } else {
                setDescriptor.tieBreakValueTeamOne = newValue
            }
        }
    }
    
    private var disableValues: [Int] {
        if let valueTeamOne = setDescriptor.valueTeamOne {
            return setFormat.disableValuesForTeamTwo(with: valueTeamOne)
        }
        return []
    }
    
    private var disableTieBreakValues: [Int] {
        if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne {
            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 = setDescriptor.valueTeamOne {
            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 = setDescriptor.tieBreakValueTeamOne, let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo {
            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 setDescriptor.tieBreakValueTeamOne != 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: $setDescriptor.valueTeamOne, initialValueRight: $setDescriptor.valueTeamTwo, 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: $setDescriptor.tieBreakValueTeamOne, initialValueRight: $setDescriptor.tieBreakValueTeamTwo, shouldDisplaySteppers: showTieBreakInputView, isTieBreak: true)
                }
            }
        }
        .onChange(of: setDescriptor.valueTeamOne) {
            if let newValue = setDescriptor.valueTeamOne {
                if newValue == setFormat.scoreToWin - 1 && setFormat.tieBreak == 8 {
                    setDescriptor.valueTeamTwo = setFormat.scoreToWin
                } else if newValue == setFormat.scoreToWin - 2 && setFormat.tieBreak == 8 {
                    setDescriptor.valueTeamTwo = setFormat.scoreToWin
                } else if newValue == setFormat.scoreToWin - 1 {
                    setDescriptor.valueTeamTwo = setFormat.scoreToWin + 1
                } else if newValue <= setFormat.scoreToWin - 2 {
                    setDescriptor.valueTeamTwo = setFormat.scoreToWin
                } else if newValue > 10 && setFormat == .superTieBreak {
                    setDescriptor.valueTeamTwo = newValue - 2
                } else if newValue > 15 && setFormat == .megaTieBreak {
                    setDescriptor.valueTeamTwo = newValue - 2
                }

            }
        }
        .onChange(of: setDescriptor.valueTeamTwo) {
            if setDescriptor.valueTeamOne != nil && setDescriptor.valueTeamTwo != nil {
                showSetInputView = false
            }
        }
        .onChange(of: setDescriptor.tieBreakValueTeamOne) {
            if let newValue = setDescriptor.tieBreakValueTeamOne, setDescriptor.tieBreakValueTeamTwo == nil {
                if newValue > 7 {
                    setDescriptor.tieBreakValueTeamTwo = newValue - 2
                }
                if newValue == 6 {
                    setDescriptor.tieBreakValueTeamTwo = newValue + 2
                }
                if newValue <= 5 {
                    setDescriptor.tieBreakValueTeamTwo = 7
                }
            }
            else if let newValue = setDescriptor.tieBreakValueTeamOne, let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo {
                if newValue > 6 && tieBreakValueTeamTwo < newValue {
                    setDescriptor.tieBreakValueTeamTwo = newValue - 2
                }
                if newValue > 6 && tieBreakValueTeamTwo > newValue {
                    setDescriptor.tieBreakValueTeamTwo = newValue + 2
                }
                if newValue == 6 {
                    setDescriptor.tieBreakValueTeamTwo = newValue + 2
                }
                if newValue <= 5 {
                    setDescriptor.tieBreakValueTeamTwo = 7
                    showTieBreakInputView = false
                }
            }
        }
        .onChange(of: setDescriptor.tieBreakValueTeamTwo) {
            if let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne, tieBreakValueTeamOne <= 5 {
                showTieBreakInputView = false
            } else {
                if let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo {
                    if tieBreakValueTeamTwo > 6 && tieBreakValueTeamTwo > setDescriptor.tieBreakValueTeamOne ?? 0 {
                        setDescriptor.tieBreakValueTeamOne = tieBreakValueTeamTwo - 2
                    }
                    if tieBreakValueTeamTwo > 4 && tieBreakValueTeamTwo < setDescriptor.tieBreakValueTeamOne ?? 0 {
                        setDescriptor.tieBreakValueTeamOne = tieBreakValueTeamTwo + 2
                    }
                }
                
                if let tieBreakValueTeamTwo = setDescriptor.tieBreakValueTeamTwo, let tieBreakValueTeamOne = setDescriptor.tieBreakValueTeamOne {
                    if tieBreakValueTeamTwo < 6 && tieBreakValueTeamOne == 7 {
                        showTieBreakInputView = false
                    }
                }

            }
        }
        .listRowSeparator(.hidden)
    }
}
