using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public sealed class SpaceStantion: IInteractableObject, ITradeProvider
{
    public string Name { get; }
    public Vector3 Position { get; }

    public string TypeId => Type.Id;
    public readonly int Id;
    public readonly Quaternion Rotation;

    public readonly SpaceStantionType Type;
    public Container Resources { get; } = new Container();

    public readonly List<CostModifier> Modifiers = new List<CostModifier>();

    public readonly Container LocalCostPercentModifiers = new Container();
    private const float thresholdPercent = 8;  // Minimum profit value

    public string[] GetPublicModifiers() => Modifiers.Select(modifier => modifier.PublicId).Where(modifierName => !string.IsNullOrEmpty(modifierName)).ToArray();

    public SpaceStantion(int id, Vector3 position, Quaternion rotation, string stantionName, SpaceStantionType stantionType) {
        Id = id;
        Rotation = rotation;
        Position = position;
        Name = stantionName;
        Type = stantionType;
    }


    private const float BuySellOffset = 0.06f;
    public string[] GetConsumptionItems()
    {
        var random = new System.Random(Id);
        const float showItemsPercent = 30;  // TODO add trader skill
        return LocalCostPercentModifiers.Items.Where(item => item.Value > thresholdPercent && random.Next(0, 100) < showItemsPercent).Select(item => item.Key).ToArray();
    }
    public string[] GetProductionItems()
    {
        var random = new System.Random(Id);
        const float showItemsPercent = 30;  // TODO add trader skill
        return LocalCostPercentModifiers.Items.Where(item => item.Value < -thresholdPercent && random.Next(0, 100) < showItemsPercent).Select(item => item.Key).ToArray();
    }

    public void AddModifier(CostModifier modifier)
    {
        LocalCostPercentModifiers[modifier.ResourceId] = Mathf.RoundToInt(modifier.Percent * UnityEngine.Random.Range(0.5f, 1.5f));
        Modifiers.Add(modifier);
        if (modifier.Percent > 0)
        {
            Resources[modifier.ResourceId] = 0;
        }
        else
        {
            Resources[modifier.ResourceId] += Mathf.RoundToInt(Type.Stock * UnityEngine.Random.Range(0.5f, 1.5f));
        }
    }

    public void RemoveEndedModifiers(int turn) {
        Modifiers.RemoveAll(modifier => modifier.EndTurn <= turn);
    }

    public int GetResourceBuyCost(string resourceId)
    {
        return Mathf.RoundToInt(GetResourceCost(resourceId) * (1 + BuySellOffset));
    }

    public int GetResourceSellCost(string resourceId)
    {
        return Mathf.RoundToInt(GetResourceCost(resourceId) * (1 - BuySellOffset));
    }

    private float GetResourceCost(string resourceId)
    {
        var baseCost = Type.Economy.GetBaseCost(resourceId);
        var costFactor = 1f + LocalCostPercentModifiers[resourceId] * 0.01f;
        // Debug.LogError($"{resourceId} cost {baseCost} count {count} consumption {consumption} stock {stock} costFactor {costFactor} ");
        return costFactor * baseCost;
    }

    public void RandomResourceMove()
    {
        foreach (var id in Type.Economy.ResourceIds)
        {
            RandomMoveResource(id);
        }
    }

    private void RandomMoveResource(string resourceId)
    {
        var resourceCount = Resources[resourceId];
        var negativeModifiers = Modifiers.Where(modifier => modifier.ResourceId == resourceId).Where(modifier => modifier.Percent > 0).Count();
        if (negativeModifiers > 0 && resourceCount == 0)
            return;
        var positiveModifiers = Modifiers.Where(modifier => modifier.ResourceId == resourceId).Where(modifier => modifier.Percent < 0).Count();
        if (positiveModifiers > 0 && resourceCount > Type.Stock * 0.5f)
            return;
        if (negativeModifiers > 0 || positiveModifiers > 0)
            Modifiers.RemoveAll(modifier => modifier.ResourceId == resourceId);

        var consumptionPercent = Type.GetConsumption(resourceId);
        var needCount = Type.Stock * (1f + consumptionPercent / 100f);
        var randomChamge = Mathf.RoundToInt(UnityEngine.Random.Range(0.1f, 0.4f) * Type.Stock);
        var localModifier = LocalCostPercentModifiers[resourceId];
        localModifier += Mathf.RoundToInt(UnityEngine.Random.Range(0, 0.25f) * -consumptionPercent);
        if (resourceCount < needCount * 0.5f) {
            Resources[resourceId] = resourceCount + randomChamge;
        }
        else
        {
            if (resourceCount > needCount * 1.5f)
            {
                Resources[resourceId] = resourceCount - randomChamge;
            }
            else
            {
                var randomDirection = (UnityEngine.Random.Range(0, 100) < 50) ? -1 : 1;
                Resources[resourceId] = resourceCount + randomChamge * randomDirection;
                localModifier += UnityEngine.Random.Range(-10, 10);
            }
        }
        LocalCostPercentModifiers[resourceId] = Mathf.Clamp(localModifier, -40 - consumptionPercent, 40 - consumptionPercent);
    }
}