/*
<copyright file="BGGCCellA.cs" company="BansheeGz">
    Copyright (c) 2018-2021 All Rights Reserved
</copyright>
*/

using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;

#endif

namespace BansheeGz.BGDatabase
{
    /// <summary>
    /// reference to a table's cell 
    /// </summary>
    public abstract class BGGCCellA : BGGCRowA
    {
        //these are the references to database cell
        [SerializeField] [HideInInspector] private string fieldId;
        private BGField field;


        public BGField Field
        {
            get
            {
                if (field != null && !field.IsDeleted && field.Meta != null) return field;
                var meta = Meta;
                if (meta == null) return null;
                field = null;
                if (string.IsNullOrEmpty(fieldId)) return null;
                if (!BGId.TryParse(fieldId, out var databaseFieldId)) return null;
                field = meta.GetField(databaseFieldId, false);

                return field;
            }
        }


        public BGGCCell? GetCell(GameObject target)
        {
            /*
            if (!BGRepo.DefaultRepoLoaded) BGRepo.Load();
            if (!BGRepo.Ok) return null;
            */
            var f = Field;
            if (f == null) return null;
            var e = GetEntity(target);
            if (e == null) return null;
            return new BGGCCell(f, e);
        }

        public abstract bool IsSupported(BGField field);

        public struct BGGCCell
        {
            public readonly BGField field;
            public readonly BGEntity row;

            public BGGCCell(BGField field, BGEntity row)
            {
                this.field = field;
                this.row = row;
            }

            public object Value
            {
                get => field.GetValue(row.Index);
                set => field.SetValue(row.Index, value);
            }
        }
        
        // +--------------------------------------------------------------------------------------+
        // | EDITOR                                                                               |
        // +--------------------------------------------------------------------------------------+
#if UNITY_EDITOR

        public override void EditorGui()
        {
            base.EditorGui();
            //field
            var currentFieldIndex = 0;
            BGField currentField = null;
            var currentMeta = Meta;
            if (currentMeta != null)
            {
                if (BGId.TryParse(fieldId, out var fId))
                {
                    currentField = currentMeta.GetField(fId, false);
                    if (currentField != null && !IsSupported(currentField)) currentField = null;
                }
            }

            var fieldOptions = new List<string>();
            var fields = new List<BGField>();
            if (currentMeta == null) fieldOptions.Add("[Select meta first]");
            else
            {
                fieldOptions.Add("[None]");
                currentMeta.FindFields(fields, IsSupported);
                for (var i = 0; i < fields.Count; i++)
                {
                    var f = fields[i];
                    if (f == currentField) currentFieldIndex = i + 1;
                    fieldOptions.Add(f.Name);
                }
            }

            var newFieldIndex = EditorGUILayout.Popup("Field", currentFieldIndex, fieldOptions.ToArray(),
                currentFieldIndex == 0 ? new GUIStyle(EditorStyles.popup) {normal = {textColor = Color.red}} : EditorStyles.popup
            );
            if (newFieldIndex != currentFieldIndex)
            {
                if (newFieldIndex == 0)
                {
                    currentField = null;
                    fieldIdProp = null;
                }
                else
                {
                    currentField = fields[newFieldIndex - 1];
                    fieldIdProp = currentField.Id.ToString();
                }
            }
        }

        protected string fieldIdProp
        {
            get => Prop(nameof(fieldId)).stringValue;
            set => Prop(nameof(fieldId)).stringValue = value;
        }


        protected override void OnDisableEditorChild()
        {
            base.OnDisableEditorChild();
            field = null;
        }

        protected override void OnMetaChange()
        {
            base.OnMetaChange();
            fieldIdProp = null;
        }

#endif
    }
}