import Foundation

final class WeddingPlayer: CardHoldingPlayer {

    enum State {
        case requiresAction
        case offersWedding
        case wouldAcceptWedding
        case withdrawnFromAuction
        case selectsGame
    }

    var state: State

    var requiresAction: Bool {
        state == .requiresAction
    }

    override var selectsGame: Bool {
        get {
            state == .selectsGame
        }
        set {
            state = .selectsGame
        }
    }

    var wouldAcceptWedding: Bool {
        state == .wouldAcceptWedding
    }

    var offersWedding: Bool {
        state == .offersWedding
    }

    init(player: BiddingPlayer, offersWedding: Bool) {
        self.state = offersWedding ? .offersWedding : .requiresAction
        super.init(player: player)
    }

    override var states: [PlayerState] {
        var states = super.states
        if offersWedding {
            states.append(.isWeddingOfferer)
        }
        return states
    }

    override var actions: [PlayerAction] {
        guard state == .requiresAction else {
            return []
        }
        return [.increaseOrMatchGame, .withdrawFromAuction, .acceptWedding]
    }

    override var isNextActor: Bool {
        get {
            switch state {
            case .requiresAction, .selectsGame:
                return true
            default:
                return false
            }
        }
        set { }
    }

    func canExchange(card: Card) -> Bool {
        cards.filter { !$0.isTrump(in: .hochzeit) }.contains(card)
    }

    var exchangeableCards: [PlayableCard] {
        cards.map { $0.playable(!$0.isTrump(in: .hochzeit)) }
    }

    func replaceWeddingCard(with card: Card) -> Card {
        let ownCardIndex = cards.firstIndex { $0.isTrump(in: .hochzeit)}!
        let ownCard = cards.remove(at: ownCardIndex)
        cards.append(card)
        cards = cards.sortedCards(forGame: .hochzeit)
        return ownCard
    }

    func replace(_ card: Card, with trumpCard: Card) {
        cards = (cards.filter { $0 != card } + [trumpCard]).sortedCards(forGame: .hochzeit)
    }

    override var info: PlayerInfo {
        var info = super.info
        info.leadsGame = offersWedding || selectsGame
        return info
    }
}
