Imports System.Collections.Generic
Imports CharterDotCom.CommonEntities.Library.Enumerations
Imports System.Web

<Serializable()> _
Public Class BLProductCatalog
    Implements ICatalog

    Private m_catalog As ProductCatalog
    Private m_cart As ICart
    Private m_bundles As Dictionary(Of String, ICartItem)
    Private m_servicePlans As Dictionary(Of String, ICartItem)

    Public Sub New(ByVal objCatalog As ProductCatalog)
        Dim sp_basic As BLServicePlan = Nothing
        m_bundles = New Dictionary(Of String, ICartItem)
        m_servicePlans = New Dictionary(Of String, ICartItem)
        m_cart = New BLShoppingCart

        m_catalog = objCatalog
        ' service plans
        Dim blSP As BLServicePlan
        For Each sp As ServicePlan In m_catalog.ServicePlans.Values
            blSP = New BLServicePlan(sp)
            If sp.ID <> Common.m_EBASIC_SERVICEPLAN_ID Then
                m_servicePlans.Add(blSP.ID, blSP)
            Else
                sp_basic = blSP
            End If
        Next
        If sp_basic IsNot Nothing Then
            m_servicePlans.Add(sp_basic.ID, sp_basic)
        End If
        ' bundles
        Dim blServicePlans As Dictionary(Of String, ISubCartItem)
        Dim blBundle As BLBundle
        For Each b As Bundle In m_catalog.Bundles.Values
            blServicePlans = New Dictionary(Of String, ISubCartItem)
            For Each sp As ServicePlan In b.ServicePlans.Values
                blServicePlans.Add(ItemType.ServicePlan & sp.ID, DirectCast(m_servicePlans(ItemType.ServicePlan & sp.ID), BLServicePlan))
            Next
            blBundle = New BLBundle(b, blServicePlans)
            m_bundles.Add(blBundle.ID, blBundle)
        Next



    End Sub


    Public ReadOnly Property Cart() As ICart Implements ICatalog.Cart
        Get
            Return m_cart
        End Get
    End Property

    Public ReadOnly Property Bundles() As Dictionary(Of String, ICartItem) Implements ICatalog.Bundles
        Get
            Return m_bundles
        End Get
    End Property

    Public ReadOnly Property ServicePlans() As Dictionary(Of String, ICartItem) Implements ICatalog.ServicePlans
        Get
            Return m_servicePlans
        End Get
    End Property

    'Public ReadOnly Property Promotions() As Dictionary(Of String, ICartItem) Implements ICatalog.Promotions
    '  Get
    '    Return m_promotions
    '  End Get
    'End Property

    Public Sub Refresh(ByVal item As ICartItem, ByVal available As Boolean, ByVal selected As Boolean, ByVal cartItems As Dictionary(Of String, CartSelections))
        Try
            Select Case item.Type
                Case ItemType.Bundle
                    Dim b As BLBundle = CType(Bundles(item.ID), BLBundle)
                    b.IsSelected = selected
                    b.IsAvailable = available
                    For Each subItem As BLServicePlan In b.ServicePlans.Values
                        RefreshServicePlan(subItem, available, selected, cartItems)
                        If m_servicePlans.ContainsKey(subItem.ID) Then
                            RefreshServicePlan(DirectCast(m_servicePlans(subItem.ID), BLServicePlan), available, selected, cartItems)
                        End If
                    Next
                Case ItemType.ServicePlan
                    Dim sp As BLServicePlan = CType(m_servicePlans(item.ID), BLServicePlan)
                    RefreshServicePlan(sp, available, selected, cartItems)
                Case Else
                    Throw New ApplicationException("Unknown Type")
            End Select
        Catch ex As ApplicationException
            Throw
        Catch ex As Exception
            Throw New ApplicationException("Cannot refresh catalog", ex)
        End Try
    End Sub

    Private Sub RefreshServicePlan(ByVal sp As BLServicePlan, ByVal available As Boolean, ByVal selected As Boolean, ByVal cartItems As Dictionary(Of String, CartSelections))
        sp.IsSelected = selected
        sp.IsAvailable = available
        For Each subItem As BLFeature In sp.Features.Values
            RefreshFeature(subItem, available, selected, cartItems)
        Next
    End Sub

    Public Sub RefreshFeature(ByVal f As BLFeature, ByVal available As Boolean, ByVal selected As Boolean, ByVal cartItems As Dictionary(Of String, CartSelections))
        Dim optionSelection As Boolean = False
        Try
            If f.FeatureType = FeatureType.IsIncluded Then

                ' this is a included feature for a service plan
                f.ISSelected = selected
                f.IsAvailable = available
            Else

                ' this is a optional feature 
                If f.Choices Is Nothing OrElse f.Choices.Count = 0 Then
                    ' optional feature without choices

                    If cartItems.ContainsKey(f.ID) Then
                        ' customization is in selected list
                        f.ISSelected = True
                        If f.QuantitySelected < f.MaxSelection Then
                            '  quantity selected is less than maximum selections allowed so this feature should be  available
                            f.IsAvailable = True
                        Else
                            ' quantity selected is equal to maximum selections allowed so this featureshould be un available
                            f.IsAvailable = False
                        End If
                    Else
                        ' this customization is not in selected list
                        f.IsAvailable = True
                        f.ISSelected = False
                        f.QuantitySelected = 0
                    End If

                Else
                    ' optional feature with choices

                    For Each c As BLFeature In f.Choices.Values
                        ' loop through all the choices of this feature
                        If f.ChoicesSelection.Contains(c.ID) Then
                            ' choice is in selected cart items
                            ' select parent(feature) of this feature
                            optionSelection = True

                            If f.MaxSelection <= 1 Then
                                ' this feature can be selected only once
                                If cartItems.ContainsKey(c.ID) Then
                                    If Not cartItems(c.ID).FeatureType = FeatureType.IsIncluded Then
                                        ' if this not an included item type
                                        ' this is required to carry choice selection from one service plan to other.
                                        ' when moving from biggest to bigger we don't want HBO and STARZ to be selected in Bigger 
                                        If f.ChoicesSelection.IndexOf(c.ID) < f.MinChoiceSelection Then
                                            ' in selected choices list first few(min number of choices allowed) should be placeholders other selections should be customizations
                                            c.FeatureType = FeatureType.IsPlaceholder
                                            If c.ID = CStr(HttpContext.Current.Application(Common.m_TOTALVIEWID)) Or c.ID = CStr(HttpContext.Current.Application(Common.m_DIGITALVIEWID)) Then
                                                If Not HttpContext.Current.Application(Common.m_VIEWPRICEADJUST) Is Nothing Then
                                                    c.Price = CDec(c.ListPrice - CDec(HttpContext.Current.Application(Common.m_VIEWPRICEADJUST)))
                                                End If
                                            End If
                                        Else
                                            If c.ID = CStr(HttpContext.Current.Application(Common.m_TOTALVIEWID)) Or c.ID = CStr(HttpContext.Current.Application(Common.m_DIGITALVIEWID)) Then
                                                c.Price = c.ListPrice
                                            End If
                                            c.FeatureType = FeatureType.IsCustomization
                                        End If
                                        c.ISSelected = True
                                        c.IsAvailable = False
                                    End If
                                Else
                                    ' if this not an included item type
                                    ' this is required to carry choice selection from one service plan to other.
                                    ' when moving from biggest to bigger we don't want HBO and STARZ to be selected in Bigger 
                                    If f.ChoicesSelection.IndexOf(c.ID) < f.MinChoiceSelection Then
                                        ' in selected choices list first few(min number of choices allowed) should be placeholders other selections should be customizations
                                        c.FeatureType = FeatureType.IsPlaceholder
                                        If c.ID = CStr(HttpContext.Current.Application(Common.m_TOTALVIEWID)) Or c.ID = CStr(HttpContext.Current.Application(Common.m_DIGITALVIEWID)) Then
                                            If Not HttpContext.Current.Application(Common.m_VIEWPRICEADJUST) Is Nothing Then
                                                c.Price = CDec(c.ListPrice - CDec(HttpContext.Current.Application(Common.m_VIEWPRICEADJUST)))
                                            End If
                                        End If
                                    Else
                                        c.FeatureType = FeatureType.IsCustomization
                                        If c.ID = CStr(HttpContext.Current.Application(Common.m_TOTALVIEWID)) Or c.ID = CStr(HttpContext.Current.Application(Common.m_DIGITALVIEWID)) Then
                                            c.Price = c.ListPrice
                                        End If
                                    End If
                                    c.ISSelected = True
                                    c.IsAvailable = False
                                End If
                            Else
                                ' this feature can be seleted more than once
                                c.QuantitySelected = 0
                                For Each id As String In f.ChoicesSelection
                                    ' in this scenario selected choices list will have selection for the each feature they selected
                                    If id = c.ID Then
                                        c.ISSelected = True
                                        c.QuantitySelected += 1
                                        If c.QuantitySelected < f.MaxChoiceSelection Then
                                            ' quantity is less than allowed selections 
                                            c.IsAvailable = True
                                        Else
                                            c.IsAvailable = False
                                        End If
                                    End If
                                Next
                            End If
                        Else
                            ' this choice is not in selected cart items 
                            c.ISSelected = False
                            c.IsAvailable = True
                            c.QuantitySelected = 0
                        End If
                    Next
                    f.ISSelected = optionSelection
                End If
            End If
        Catch ex As Exception
            Throw New ApplicationException("Error refershing Feature", ex)
        End Try
    End Sub

    Public Sub ClearCart()
        For Each item As ICartItem In m_cart.CartItems.Values
            Refresh(item, True, False, New Dictionary(Of String, CartSelections))
        Next
        DirectCast(m_cart, BLShoppingCart).Clear()
    End Sub

End Class
