using System;
using Net.Eagle0.Eagle.Api;
using Net.Eagle0.Eagle.Views;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace eagle {
    using ProvinceId = Int32;

    public class TradeCommandSelector : CommandSelector {
        public TMP_Text buyPrice;
        public TMP_Text sellPrice;
        public Slider slider;
        public TMP_Text goldText;
        public TMP_Text foodText;
        public TMP_Text description;
        public RectTransform startingPositionIndicator;

        public override AvailableCommand.SealedValueOneofCase CommandType =>
                AvailableCommand.SealedValueOneofCase.TradeCommand;
        public override string HeaderString => "Trade";
        public override string CommitButtonString => IsBuy ? "Commit Buy" : "Commit Sell";

        private TradeAvailableCommand TradeCommand => _availableCommand.TradeCommand;
        private ProvinceId ActingProvinceId => TradeCommand.ActingProvinceId;
        private ProvinceView ActingProvince => _model.Provinces[ActingProvinceId];
        private int ProvinceGoldCap => ActingProvince.FullInfo.GoldCap;
        private int ProvinceFoodCap => ActingProvince.FullInfo.FoodCap;

        private int MaxFood =>
                TradeCommand.FoodAvailable +
                (int)Math.Floor(TradeCommand.GoldAvailable / TradeCommand.FoodBuyPrice);
        private int FoodAmount => (int)slider.value;

        protected override void SetUpUI() {
            slider.minValue = 0;
            slider.maxValue = MaxFood;
            slider.value = TradeCommand.FoodAvailable;

            buyPrice.text = $"{TradeCommand.FoodBuyPrice:0.##}";
            sellPrice.text = $"{TradeCommand.FoodSellPrice:0.##}";

            // Position the starting position indicator horizontally
            if (startingPositionIndicator != null && MaxFood > 0) {
                float normalizedStart = (float)TradeCommand.FoodAvailable / MaxFood;
                // Only adjust horizontal anchor, preserve vertical anchors from prefab
                startingPositionIndicator.anchorMin =
                        new Vector2(normalizedStart, startingPositionIndicator.anchorMin.y);
                startingPositionIndicator.anchorMax =
                        new Vector2(normalizedStart, startingPositionIndicator.anchorMax.y);
                startingPositionIndicator.anchoredPosition = Vector2.zero;
            }

            SetTextFields();
        }

        public void GoldPlusClicked() {
            slider.value = Math.Max(0, slider.value - KeyModifiedAmount.Amount());
            SetTextFields();
        }

        public void FoodPlusClicked() {
            slider.value = Math.Min(MaxFood, slider.value + KeyModifiedAmount.Amount());
            SetTextFields();
        }

        public override bool EnableCommitButton =>
                !Mathf.Approximately(slider.value, TradeCommand.FoodAvailable);
        public override string DisabledCommitButtonReason => "No change";

        private bool IsBuy => FoodAmount > TradeCommand.FoodAvailable;
        private int NetFood => FoodAmount - TradeCommand.FoodAvailable;
        private int NetGold => IsBuy ? -(int)Math.Ceiling(NetFood * TradeCommand.FoodBuyPrice)
                                     : -(int)Math.Ceiling(NetFood * TradeCommand.FoodSellPrice);
        private int GoldAmount => TradeCommand.GoldAvailable + NetGold;

        public override SelectedCommand Command => new() {
            TradeCommand =
                    new TradeSelectedCommand {
                        Amount = Math.Abs(FoodAmount - TradeCommand.FoodAvailable),
                        TradeType = IsBuy ? TradeSelectedCommand.Types.TradeType.BuyFood
                                          : TradeSelectedCommand.Types.TradeType.SellFood
                    }
        };

        public void SetTextFields() {
            goldText.text = GoldAmount.ToString();
            goldText.color = GoldAmount > ProvinceGoldCap ? Color.red : Color.black;

            foodText.text = FoodAmount.ToString();
            foodText.color = FoodAmount > ProvinceFoodCap ? Color.red : Color.black;

            description.text = IsBuy ? $"Buying {NetFood} food for {-NetGold} gold"
                                     : $"Selling {-NetFood} food for {NetGold} gold";
        }
    }
}