using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public sealed class ServiceUIFoldPanel : MonoBehaviour
{
    [SerializeField]
    private Text stantionName = null;
    [SerializeField]
    private Button backButton = null;
    [SerializeField]
    private StarMapGenerator starmap = null;
    [SerializeField]
    private Profile profile = null;
    [SerializeField]
    private Text fuelCountLabel = null;
    [SerializeField]
    private Button refuelButton = null;
    [SerializeField]
    private Text armorCountLabel = null;
    [SerializeField]
    private Button repairButton = null;
    [SerializeField]
    private CreditsUICounter creditsCounter = null;
    [SerializeField]
    private SpaceUICounter spaceCounter = null;
    [SerializeField]
    private Text shipStatusLabel = null;
    public Player Player => profile.Player;
    public StarShip StarShip => profile.Player.StarShip;

    public void Show(string name)
    {
        gameObject.SetActive(true);
        refuelButton.interactable = StarShip.Fuel < StarShip.MaxFuel;
        repairButton.interactable = StarShip.Armor < StarShip.MaxArmor;
        UpdateFuelLabel(StarShip.Fuel, StarShip.MaxFuel);
        UpdateArmorLabel(StarShip.Armor, StarShip.MaxArmor);
        creditsCounter.Show(Player.Credits);
        spaceCounter.Show(StarShip.GetCargoSpace(), StarShip.GetFullSpace());
        ShowEquipment(StarShip);
        stantionName.text = name;
    }

    public void Hide() => gameObject.SetActive(false);

    private void RefuelShip()
    {
        var needCount = StarShip.MaxFuel - StarShip.Fuel;
        if (Player.TryBuyHyperFuel(starmap.FuelCost, needCount))
        {
            UpdateFuelLabel(StarShip.Fuel, StarShip.MaxFuel);
            creditsCounter.Show(Player.Credits);
        }
        else
        {
            creditsCounter.ShowNoCreditsEffect();
        }
    }

    private void RepairShip()
    {
        if (Player.TryBuyRepair())
        {
            UpdateArmorLabel(StarShip.Armor, StarShip.MaxArmor);
            creditsCounter.Show(Player.Credits);
        }
        else
        {
            creditsCounter.ShowNoCreditsEffect();
        }
    }

    private void UpdateFuelLabel(int fuel, int max)
    {
        fuelCountLabel.text = $"{fuel}/{max}";
    }

    private void UpdateArmorLabel(int armor, int max)
    {
        armorCountLabel.text = $"{armor}/{max}";
    }

    private void ShowEquipment(StarShip ship)
    {
        var equipment = ship.Equipment;
        shipStatusLabel.text =
            $"SHIP: {equipment.Ship.Blueprint.Id}" +
            $"\n{MergeParams(equipment.Ship.Blueprint)}" +
            $"\n" +
            $"\njump radius: {ship.MaxJumpRadius} fuel: {ship.Fuel}/{ship.MaxFuel} cargo: {ship.GetFullSpace()}" +
            $"\n" +
            $"\nEQUIPMENT:" +
            $"\nDRIVE: {GetParam(equipment.Drive)}" +
            $"\nTANK: {GetParam(equipment.Tank)}" +
            $"\nCARGO: {GetParam(equipment.CargoModule)}" +
            $"\nSHIELD: {GetParam(equipment.Shield)}" +
            $"\nWEAPON: {GetParam(equipment.Weapon)}";
    }

    private string GetParam(EquipmentSlot equip)
    {
        if (equip.Blueprint.Params == null || equip.Blueprint.Params.Count == 0) {
            return $"{equip.Blueprint.Id}";
        }
        return $"{equip.Blueprint.Id} ({MergeParams(equip.Blueprint)})";
    }

    private string MergeParams(EquipmentBlueprintParams equip)
    {
        if (equip == null || equip.Params == null)
            return string.Empty;
        return string.Join(", ", equip.Params.Select(param => $"{param.Key}: {param.Value}"));
    }

    public void Start()
    {
        refuelButton.onClick.AddListener(RefuelShip);
        repairButton.onClick.AddListener(RepairShip);
        backButton.onClick.AddListener(Hide);
    }

    private void OnDestroy()
    {
        refuelButton.onClick.RemoveListener(RefuelShip);
        repairButton.onClick.RemoveListener(RepairShip);
        backButton.onClick.AddListener(Hide);
    }

    public void Update()
    {
        if (Input.GetKey(KeyCode.Escape))
        {
            Hide();
        }
    }
}
