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

public sealed class StarShip: IInteractableObject, ITradeProvider
{
    public readonly int FactionId;
    public string Name => Equipment.Ship.Blueprint.Id;
    public Vector3 Position { get; set; } = new Vector3(0, 0, 50);
    public Quaternion Rotation = Quaternion.identity;

    public Container Resources { get; }
    public readonly ShipEquipment Equipment;

    public int Armor { get; private set; }
    public int MaxArmor => Equipment.Armor;
    public int Shield { get; private set; }
    public int MaxShield => Equipment.PowerShield;


    public int Fuel { get; private set; }
    public int MaxFuel => Equipment.FuelCapacity;

    public float MaxJumpRadius => Equipment.JumpRadius;

    public int Damage => Equipment.Damage;

    public int GetFullSpace() => Equipment.CargoSpace;
    public int GetCargoSpace() => Resources.Items.Values.Sum();
    public int GetEmptySpace() => GetFullSpace() - GetCargoSpace();

    // equipment
    public StarShip(
        Vector3 position,
        Quaternion rotation,
        int factionId,
        ShipEquipment equipment,
        int armor = 0,
        int fuel = 0,
        Dictionary<string, int> items = null)
    {
        FactionId = factionId;
        Position = position;
        Rotation = rotation;
        Fuel = fuel;
        Resources = new Container(items);
        Equipment = equipment;
        Armor = armor <= 0 ? MaxArmor : armor;
        Shield = MaxShield;
    }

    public int GetResourceSellCost(string resourceId) => 0; // for loot
    public int GetResourceBuyCost(string resourceId) => 0; // for loot

    public void RestoreShield()
    {
        Shield = MaxShield;
    }

    public void Hit(int damage)
    {
        Shield -= damage;
        if (Shield < 0)
        {
            damage = -Shield;
            Shield = 0;
        }
        else
        {
            damage = 0;
        }
        Armor -= damage;
        if (Armor < 0)
        {
            Armor = 0;
        }
    }

    public bool IsPirate() => FactionId < 0;

    public int GetFuelCost(float distance)
    {
        var fuelCostFactor = 1f;
        return Mathf.CeilToInt(distance * fuelCostFactor);
    }

    public void ConsumeFuel(int count)
    {
        Fuel -= count;
    }

    public void Repair()
    {
        Armor = MaxArmor;
    }
}
