using System.Collections.Generic;
using UnityEngine;

namespace eagle {
    /// <summary>
    /// Manages 256x1 lookup textures for per-province border highlighting.
    /// Border color and width are set per province and uploaded each frame
    /// when dirty, mirroring ProvinceColorManager's batched approach.
    /// Also manages a highlight-group lookup so the shader can suppress
    /// highlight borders between provinces in the same group (e.g. same faction).
    /// </summary>
    public class ProvinceBorderManager : MonoBehaviour {
        [Header("Material")]
        public Material provinceMapMaterial;

        [Header("Default Borders")]
        public float defaultBorderWidth = 0.5f;
        public Color defaultBorderColor = new Color(0.15f, 0.1f, 0.05f, 0.8f);

        private Texture2D _borderColorLookup;
        private Texture2D _borderWidthLookup;
        private Texture2D _highlightGroupLookup;
        private Color[] _borderColors;
        private Color[] _borderWidths;
        private Color[] _highlightGroups;
        private bool _dirty;
        private bool _groupDirty;

        void Awake() {
            _borderColorLookup = new Texture2D(256, 1, TextureFormat.RGBA32, false);
            _borderColorLookup.filterMode = FilterMode.Point;
            _borderColorLookup.wrapMode = TextureWrapMode.Clamp;

            _borderWidthLookup = new Texture2D(256, 1, TextureFormat.RGBA32, false);
            _borderWidthLookup.filterMode = FilterMode.Point;
            _borderWidthLookup.wrapMode = TextureWrapMode.Clamp;

            _highlightGroupLookup = new Texture2D(256, 1, TextureFormat.RGBA32, false);
            _highlightGroupLookup.filterMode = FilterMode.Point;
            _highlightGroupLookup.wrapMode = TextureWrapMode.Clamp;

            _borderColors = new Color[256];
            _borderWidths = new Color[256];
            _highlightGroups = new Color[256];
            for (int i = 0; i < 256; i++) {
                _borderColors[i] = Color.clear;
                _borderWidths[i] = Color.clear;
                _highlightGroups[i] = Color.clear;
            }

            _borderColorLookup.SetPixels(_borderColors);
            _borderColorLookup.Apply();
            _borderWidthLookup.SetPixels(_borderWidths);
            _borderWidthLookup.Apply();
            _highlightGroupLookup.SetPixels(_highlightGroups);
            _highlightGroupLookup.Apply();

            provinceMapMaterial.SetTexture("_BorderColorLookup", _borderColorLookup);
            provinceMapMaterial.SetTexture("_BorderWidthLookup", _borderWidthLookup);
            provinceMapMaterial.SetTexture("_HighlightGroupLookup", _highlightGroupLookup);
            provinceMapMaterial.SetFloat("_DefaultBorderWidth", defaultBorderWidth);
            provinceMapMaterial.SetColor("_DefaultBorderColor", defaultBorderColor);
        }

        public void SetProvinceBorder(int provinceId, Color color, float widthScreenPx) {
            if (provinceId < 0 || provinceId > 255) return;
            _borderColors[provinceId] = color;
            _borderWidths[provinceId] = new Color(widthScreenPx / 255f, 0, 0, 0);
            _dirty = true;
        }

        public void ClearProvinceBorder(int provinceId) {
            if (provinceId < 0 || provinceId > 255) return;
            _borderColors[provinceId] = Color.clear;
            _borderWidths[provinceId] = Color.clear;
            _dirty = true;
        }

        public void SetHighlightGroup(IList<int> provinceIds) {
            for (int i = 0; i < 256; i++) { _highlightGroups[i] = Color.clear; }
            var groupColor = new Color(1f / 255f, 0, 0, 0);
            foreach (var id in provinceIds) {
                if (id >= 0 && id <= 255) { _highlightGroups[id] = groupColor; }
            }
            _groupDirty = true;
        }

        public void ClearHighlightGroup() {
            for (int i = 0; i < 256; i++) { _highlightGroups[i] = Color.clear; }
            _groupDirty = true;
        }

        void LateUpdate() {
            if (_dirty) {
                _borderColorLookup.SetPixels(_borderColors);
                _borderColorLookup.Apply();
                _borderWidthLookup.SetPixels(_borderWidths);
                _borderWidthLookup.Apply();
                _dirty = false;
            }
            if (_groupDirty) {
                _highlightGroupLookup.SetPixels(_highlightGroups);
                _highlightGroupLookup.Apply();
                _groupDirty = false;
            }
        }

        void OnDestroy() {
            if (_borderColorLookup != null) Destroy(_borderColorLookup);
            if (_borderWidthLookup != null) Destroy(_borderWidthLookup);
            if (_highlightGroupLookup != null) Destroy(_highlightGroupLookup);
        }
    }
}
