//
//  ResiliationViewModel.swift
//  AlloVoisinsSwiftUI
//
//  Created by Victor on 14/10/2024.
//

import Foundation
import SwiftUICore

class ResiliationViewModel: ObservableObject {
    @Published var resiliationType: ResiliationType
    @Published var resiliationCheckSteps: [ResiliationCheckStep]
    @Published var resiliationReasons: [ResiliationReason]
    @Published var selectedReason: ResiliationReason?
    @Published var promotionalScreens: [ResiliationPromotionalScreen] = []
    @Published var currentScreen: Screen = .checkSteps

    enum Screen: Equatable {
        case checkSteps
        case reason
        case promotional(ResiliationPromotionalScreen)
        case final
    }

    init(resiliationType: ResiliationType) {
        self.resiliationType = resiliationType
        self.resiliationCheckSteps = ResiliationCheckStep.getCheckSteps(for: resiliationType)
        self.resiliationReasons = ResiliationReason.getRadioResiliation(for: resiliationType)
    }

    func moveToReason() {
        currentScreen = .reason
    }

    func setSelectedReason(_ reason: ResiliationReason) {
        selectedReason = reason
        promotionalScreens = selectResiliationPromotions(
            availablePromotions: getAvailablePromotionalScreens(for: reason),
            eligibleScreens: getEligiblePromotionalScreens()
        )

        if promotionalScreens.isEmpty {
            currentScreen = .final
        } else {
            currentScreen = .promotional(promotionalScreens.removeFirst())
        }
    }

    func moveToNextPromotionalScreen() {
        if !promotionalScreens.isEmpty {
            currentScreen = .promotional(promotionalScreens.removeFirst())
        } else {
            currentScreen = .final
        }
    }

    private func selectResiliationPromotions(availablePromotions: [ResiliationPromotionalScreen], eligibleScreens: [ResiliationPromotionalScreen]) -> [ResiliationPromotionalScreen] {
        let shuffledArray1 = availablePromotions.shuffled()

        let commonPromotions = shuffledArray1.filter { promotion in
            eligibleScreens.contains(promotion)
        }

        let result = commonPromotions.map { $0 }

        return Array(result.prefix(2))
    }

    private func getAvailablePromotionalScreens(for reason: ResiliationReason) -> [ResiliationPromotionalScreen] {
        switch reason {
        case .noPositiveResponses:
            return [.externalReview, .webinarPresentation, .profileCompletion]
        case .uninterestingRequests:
            return [.webinarPresentation, .editPerimeter, .onlyProSearches]
        case .lowDemand:
            return [.externalReview, .profileCompletion, .editPerimeter, .oneMonthBoosterOffered]
        case .betterPlatforms:
            // TODO: Rajouter présentation Logiciel
            return [.oneMonthBoosterOffered, .allovoisinsPromotion, .extendMyTrialPeriod, .webinarPresentation]
        case .notPro:
            return [.askPartProStatusChange]
        case .insufficientTime:
            return [.extendMyTrialPeriod]
        case .misunderstoodPremier:
            // TODO: Check si c'est le bon .cusrommerSupport*
            return [.webinarPresentation, .customerSupportForPro]
        default:
            return [.allovoisinsPromotion]
        }
    }

    private func getEligiblePromotionalScreens() -> [ResiliationPromotionalScreen] {
        return [.extendMyTrialPeriod, .profileCompletion, .allovoisinsPromotion]
    }

    private func getPromotionalScreen(for screen: ResiliationPromotionalScreen) -> any View {
        switch screen {
        case .externalReview:
            break
        case .webinarPresentation:
            return WebinaireScreen()
        case .profileCompletion:
            return ProfileCompletionScreen()
        case .editPerimeter:
            return ResizePerimeterScreen()
        case .onlyProSearches:
            return OnlyProRequestsScreen()
        case .oneMonthBoosterOffered:
            return BoosterSubscriptionSelectionScreen()
        case .allovoisinsPromotion:
            return AlloVoisinReputationScreen()
        case .extendMyTrialPeriod:
            return MoreTimeScreen()
        case .askPartProStatusChangeWithCancellation:
            return StatusChangeScreen()
        case .customerSupportForPro:
            return PersonalizedSupportScreen()
        case .customerSupportForPart:
            return PersonalizedSupportScreen()
        case .askPartProStatusChange:
            return StatusChangeScreen()
        case .ordersPresentation:
            break
        }

        return EmptyView()
    }

    @ViewBuilder
    func getPromotionalScreenNew(for screen: ResiliationPromotionalScreen) -> some View {
        switch screen {
        case .webinarPresentation:
            WebinaireScreen()
        case .profileCompletion:
            ProfileCompletionScreen()
        case .editPerimeter:
            ResizePerimeterScreen()
        case .onlyProSearches:
            OnlyProRequestsScreen()
        case .oneMonthBoosterOffered:
            BoosterSubscriptionSelectionScreen()
        case .allovoisinsPromotion:
            AlloVoisinReputationScreen()
        case .extendMyTrialPeriod:
            MoreTimeScreen()
        case .askPartProStatusChangeWithCancellation, .askPartProStatusChange:
            StatusChangeScreen()
        case .customerSupportForPro, .customerSupportForPart:
            PersonalizedSupportScreen()
        default:
            EmptyView()
        }
    }
}
