﻿using System;
using System.Collections.Generic;
using HutongGames.PlayMaker;
using UnityEngine;

namespace BansheeGz.BGDatabase
{
    public abstract class BGPlaymakerResetValuesA : FsmStateAction
    {
        [HutongGames.PlayMaker.Tooltip("Debug statistics to Unity Log")]
        public FsmBool debug;

        protected void DebugMessage(string message)
        {
            if (!IsOn(debug)) return;
            Debug.Log(message);
        }

        public override void Reset() => debug = null;

        private static BGRepo defaultRepo;

        public static BGRepo DefaultRepo
        {
            get
            {
                if (defaultRepo != null) return defaultRepo;
                var repo = BGRepo.I;
                byte[] defaultRepoContent;
                if (BGRepo.DefaultRepoCustomLoaderModel != null)
                {
                    defaultRepoContent = repo.RepoLoader.Load(new BGLoaderForRepo.LoadRequest(BGRepo.DefaultRepoCustomLoaderModel.Get(BGRepoCustomLoaderModel.DatabaseKey)));
                }
                else
                {
                    defaultRepoContent = repo.RepoLoader.Load(new BGLoaderForRepo.LoadRequest((string)null));
                }

                var result = new BGRepo(defaultRepoContent)
                {
                    RepoLoader = repo.RepoLoader
                };
                var partitionAddon = result.Addons.Get<BGAddonPartition>();
                partitionAddon?.OnMainDatabaseLoad();
                defaultRepo = result;
                return defaultRepo;
            }
        }

        public static void ResetInstance() => defaultRepo = null;

        protected static BGMetaEntity GetDefaultMeta(BGMetaEntity meta)
        {
            var defaultMeta = DefaultRepo.GetMeta(meta.Id);
            if (defaultMeta == null) throw new Exception($"Can not find default meta, id={meta.Id}, name={meta.Name}");
            return defaultMeta;
        }

        protected static List<BGField> GetDefaultFields(BGMetaEntity defaultMeta, List<BGField> fields)
        {
            var result = new List<BGField>(fields.Count);
            foreach (var field in fields) result.Add(defaultMeta.GetField(field.Id));
            return result;
        }

        protected static BGEntity GetDefaultEntity(BGMetaEntity defaultMeta, BGEntity entity, bool throwExceptionIfNotFound)
        {
            var defaultEntity = defaultMeta.GetEntity(entity.Id);
            if (defaultEntity == null && throwExceptionIfNotFound) throw new Exception($"Entity with id={entity.Id} (name={entity.Name})  can not be found in default repo!");
            return defaultEntity;
        }

        protected static void Copy(BGEntity defaultEntity, List<BGField> defaultFields, BGEntity entity, List<BGField> fields)
        {
            for (var i = 0; i < defaultFields.Count; i++)
            {
                var defaultField = defaultFields[i];
                var field = fields[i];
                field.CopyValue(defaultField, defaultEntity.Id, defaultEntity.Index, entity.Id);
            }
        }

        protected static int AddMissing(BGMetaEntity defaultMeta, List<BGField> defaultFields, BGMetaEntity meta, List<BGField> fields)
        {
            var result = 0;
            defaultMeta.ForEachEntity(defaultEntity =>
            {
                if (meta.HasEntity(defaultEntity.Id)) return;
                result++;
                var missingEntity = meta.NewEntity(defaultEntity.Id);
                Copy(defaultEntity, defaultFields, missingEntity, fields);
            });
            return result;
        }

        protected static int ForEachToken(FsmString tokenParameter, Action<string> action)
        {
            var count = 0;
            if (!tokenParameter.IsNone)
            {
                var fieldsValue = tokenParameter.Value;
                if (!string.IsNullOrWhiteSpace(fieldsValue))
                {
                    var tokens = fieldsValue.Split(",");
                    if (tokens.Length != 0)
                    {
                        foreach (var token in tokens)
                        {
                            count++;
                            var tokenTrimmed = token.Trim();
                            action(tokenTrimmed);
                        }
                    }
                }
            }

            return count;
        }

        protected static bool IsOn(FsmBool field) => !field.IsNone && field.Value;
       
    }
}