// Copyright (c) Strange Loop Games. All rights reserved.
// See LICENSE file in the project root for full license information.

namespace Eco.Mods.TechTree
{
    using Eco.Gameplay.Housing;
    using Eco.Core.Items;
    using Eco.Core.Plugins.Interfaces;
    using System.Collections.Generic;
    using System.Linq;
    using Eco.Gameplay.Items;
    using Eco.Gameplay.Housing.PropertyValues;
    using Eco.Shared.Localization;
    using Eco.Shared.Utils;
    using Eco.Gameplay.Settlements.Culture;
    using Eco.Shared.Items;
    using Eco.Gameplay.Housing.PropertyValues.Internal;
    using static Eco.Gameplay.Housing.PropertyValues.Internal.RoomTierUtils;

    public class HousingValues : IModInit
    {
        public static void Initialize()
        {
            //We set a housing-points penalty for multiple people in a property based on the follow table:
            //Number of residents on a property:     0    1    2    3    4     5    6    7    <more>
            //Formula of occupancy penalties. 
            //It makes following values:             0   0.33  0.5 0.6 0.66   0.71 0.75 0.78
            //The idea is to keep same cap allowing new free penalty room for new occupants. In this way cap is always the same, for 10 points rooms of same type it will be capped at 20 no matter how many residents are
            //Also this formula makes live with residents a little more convenient since they need to build less rooms per resident to be close to cap
            HousingConfig.OccupancyPenaltyGenerator = (x) => x <= 1 ? 0f : 1f-(2f/(x+1));

            //Set the limits for housing points based on each tier of material.  After the 'softcap' is reached, returns are diminised at the percent given, with 'hardcap' being the infinite limit.
            HousingConfig.SetRoomTiers(new[]
            {
                new RoomTier { TierVal = 0, SoftCap = 2f,  HardCap = 4f,  DiminishingReturnPercent = .5f },
                new RoomTier { TierVal = 1, SoftCap = 5f,  HardCap = 10f, DiminishingReturnPercent = .5f },
                new RoomTier { TierVal = 2, SoftCap = 10f, HardCap = 20f, DiminishingReturnPercent = .5f },
                new RoomTier { TierVal = 3, SoftCap = 15f, HardCap = 30f, DiminishingReturnPercent = .5f },
                new RoomTier { TierVal = 4, SoftCap = 20f, HardCap = 40f, DiminishingReturnPercent = .5f }
            });


            //Setup our room categories
            HousingConfig.SetRoomCategories(new[]
            {
                //Residency rooms
                new RoomCategory() { Color = new Color("DB48C5"),  DisplayName = Localizer.DoStr("Living Room"),   AffectsPropertyTypes = new[] { PropertyType.Residence}, SupportingRoomCategoryNames = new[] {"Seating", "Cultural" },               MaxSupportPercentOfPrimary = .25f},
                new RoomCategory() { Color = new Color("00B4A5"),  DisplayName = Localizer.DoStr("Bedroom"),       AffectsPropertyTypes = new[] { PropertyType.Residence}, SupportingRoomCategoryNames = new[] {"Living Room", "Seating" }  },
                new RoomCategory() { Color = new Color("4C7BD9"),  DisplayName = Localizer.DoStr("Kitchen"),       AffectsPropertyTypes = new[] { PropertyType.Residence}, SupportingRoomCategoryNames = new[] {"Seating" },               },
                new RoomCategory() { Color = new Color("A6E1EA"),  DisplayName = Localizer.DoStr("Bathroom"),      SupportingRoomCategoryNames = new[] {"Seating"},IsRoomValueCappedAgainstRestOfHouse = false, CapToPercentOfRestOfProperty = .2f},
                //Special room types.
                new RoomCategory() { Color = Color.Culture,        DisplayName = Localizer.DoStr("Cultural"),      AffectsPropertyTypes = new[] { PropertyType.Cultural},  MaxSupportPercentOfPrimary = .3f, SupportingRoomCategoryNames = new[] {"Seating"} },
                new RoomCategory() { Color = new Color("A300B4"),  DisplayName = Localizer.DoStr("Industrial"),    NegatesValue = true },
                //Supporting rooms, these do not generating their own unique room types but only add value to existing rooms based on the percentile value set.
                //This value cannot exceed the total value of the MaxSupportPercent.
                new RoomCategory() { Color = new Color("E5956E"),  DisplayName = Localizer.DoStr("Seating"),       CanBeRoomCategory = false, MaxSupportPercentOfPrimary = .5f },
                new RoomCategory() { Color = new Color("6BD6B4"),  DisplayName = Localizer.DoStr("Decoration"),    CanBeRoomCategory = false, SupportForAnyRoomType = true, MaxSupportPercentOfPrimary = .5f },
                new RoomCategory() { Color = new Color("FFD6B4"),  DisplayName = Localizer.DoStr("Lighting")  ,    CanBeRoomCategory = false, SupportForAnyRoomType = true, MaxSupportPercentOfPrimary = .3f },
            });
        }

        //refactor todo: move out of mods
        public static void PostInitialize()
        {
            var categoryToTags = TagAttribute.CategoryToTags ?? new Dictionary<string, string[]>();
            var tiers = new HashSet<float> { 0 };
            foreach (var item in Item.AllItems)
            {
                if (item.Hidden) continue;
                var itemTier = ItemAttribute.Get<TierAttribute>(item.Type);
                if (itemTier != null)
                    tiers.Add(itemTier.Tier);
            }

            categoryToTags["Tiers"] = tiers.OrderBy(x => x).Select(x => $"Tier {x}").ToArray();
            TagAttribute.CategoryToTags = categoryToTags;
        }
    }
}
