using System;
using System.Collections.Generic;

using Proyecto26;

using UnityEngine;
namespace XenseAR
{

public class ImageAnchorEditor : ImageAnchor, IEditor
{
    [SerializeField] private bool isShowInEditor = false;

    private mTransform _transform = new mTransform();

    private bool _isNew = false;

    private bool _isSaved = false;

    private bool _isUpdating = false;

    private bool _isEdited = false;

    private bool _isError = false;

    public bool isNew
    {
        get { return _isNew; }
        set { _isNew = value; }
    }

    public bool isEdited
    {
        get { return _isEdited; }
        set { _isEdited = value; }
    }

    public bool isError
    {
        get { return _isError; }
        set { _isError = value; }
    }

    public bool isSaved
    {
        get { return _isSaved; }
        set { _isSaved = value; }
    }

    public bool isUpdating
    {
        get { return _isUpdating; }
        set { _isUpdating = value; }
    }

    protected override void Start()
    {
        base.Start();
        target.media.Type = AnchoringMediaType.Image;
    }

    protected void Update()
    {
        _transform.FromUnity(gameObject.transform);
        if (!Utility.Compare(_transform, target.transform))
        {
            MarkAsEdited();
        }
    }

    void SetIsEditedAndOppositeIsSaved(bool check)
    {
        isEdited = check;
        isSaved = !isEdited;
    }
    public void MarkAsEdited() => SetIsEditedAndOppositeIsSaved(true);


    public void Save()
    {
        if (isUpdating) return;
        Debug.Log("Save");
        string blockID = GetComponentInParent<ARWorldBlockInfo>().GetInfo().ID;
        SetBlockID(blockID);

        string worldID = GetComponentInParent<WorldSelector>().GetWorldID();
        SetWorldID(worldID);

        isNew = false;
        isError = false;
        isSaved = false;
        isUpdating = true;

        if (string.IsNullOrEmpty(target.id))
            isNew = true;
        if (isNew)
        {
            target.media.name = gameObject.name;
            target.id = System.Guid.NewGuid().ToString();
            target.transform.FromUnity(transform);
            target.boundSize = Utility.GetBound(gameObject).size;
            target.animation = (int)gameObject.GetComponent<ImageAnchorEditor>().animationType + "";
            if (target.boundSize == Vector3.zero)
            {
                target.boundSize = Vector3.one;
            }
            string jsonStr = JsonUtility.ToJson(target);
            BackendServices.Instance.Post(new RequestHelper
            {
                SimpleForm = new Dictionary<string, string>()
            {
                {"type","AddNewAnchoringTarget" },
                {"BlockID",this.GetBlockID()},
                {"worldId", this.GetWorldID()},
                {"anchoringTargetData",jsonStr},
            },
                //            Uri = "",
            }).Then(res => OnFinishSave(res))
            .Catch(err =>
            {
                NotifySaveError($"Save Error (New Target - Backend Post): {err}");
            });
                isNew = false;
            Dictionary<string, object> parameters = new Dictionary<string, object>()
            {
                { "targetID", target.id},
                { "blockID", this.GetBlockID()},
                { "targetName", target.media.name},
                { "targetType", target.media.Type},
                { "positionX", target.transform.position.x},
                { "positionY", target.transform.position.y},
                { "positionZ", target.transform.position.z},
                { "rotationX", target.transform.orientation.x},
                { "rotationY", target.transform.orientation.y},
                { "rotationZ", target.transform.orientation.z},
                { "rotationW", target.transform.orientation.w},
                { "scaleX", target.transform.scale.x},
                { "scaleY", target.transform.scale.y},
                { "scaleZ", target.transform.scale.z},
                { "dateCreated", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")},
            };
            AnalyticsSender.Instance.SendEvent("createTarget", parameters);
        }
        else
        {
            target.media.name = gameObject.name;
            target.transform.FromUnity(transform);
            target.boundSize = Utility.GetBound(gameObject).size;
            target.animation = (int) gameObject.GetComponent<ImageAnchorEditor>().animationType + "";
            if (target.boundSize == Vector3.zero)
            {
                target.boundSize = Vector3.one;
            }
            string jsonStr = JsonUtility.ToJson(target);
            BackendServices.Instance.Post(new RequestHelper
            {
                SimpleForm = new Dictionary<string, string>()
            {
                {"type","UpdateAnchoringTarget" },
                {"anchoringTargetId",target.id },
                {"anchoringTargetData",jsonStr},
            },
                //            Uri = "",
            }).Then(res => OnFinishSave(res))
            .Catch(err =>
            {
                NotifySaveError($"Save Error (New Target - Backend Post): {err}");
            });
                Dictionary<string, object> parameters = new Dictionary<string, object>()
            {
                { "targetID", target.id},
                { "blockID", this.GetBlockID()},
                { "targetName", target.media.name},
                { "targetType", target.media.Type},
                { "positionX", target.transform.position.x},
                { "positionY", target.transform.position.y},
                { "positionZ", target.transform.position.z},
                { "rotationX", target.transform.orientation.x},
                { "rotationY", target.transform.orientation.y},
                { "rotationZ", target.transform.orientation.z},
                { "rotationW", target.transform.orientation.w},
                { "scaleX", target.transform.scale.x},
                { "scaleY", target.transform.scale.y},
                { "scaleZ", target.transform.scale.z},
                { "dateUpdated", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")},
            };
            AnalyticsSender.Instance.SendEvent("updateTarget", parameters);
        }
    }
    public void Load()
    {
        if (isNew || target == null || string.IsNullOrEmpty(target.id)) return;
        BackendServices.Instance.Post(new RequestHelper
        {
            SimpleForm = new Dictionary<string, string>()
            {
                {"type","GetAnchoringTarget" },
                {"anchoringTargetId", target.id},
            },
            //            Uri = "",
        }).Then(res => OnFinishLoad(res));
    }

    protected override bool isNeedEnable()
    {
        return algorithm.IsNeedLoad(target, transform) || isShowInEditor;
    }

    public void Remove()
    {
        if (isNew || target == null || string.IsNullOrEmpty(target.id)) return;
        BackendServices.Instance.Post(new RequestHelper
        {
            SimpleForm = new Dictionary<string, string>()
            {
                {"type","DeleteAnchoringTarget" },
                {"anchoringTargetId", target.id},
            },
            //            Uri = "",
        }).Then(res => OnFinishRemove(res));
        Dictionary<string, object> parameters = new Dictionary<string, object>()
            {
                { "targetID", target.id},
                { "blockID", this.GetBlockID()},
                { "targetName", target.media.name},
                { "targetType", target.media.Type},
                { "dateDeleted", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")},
            };
        AnalyticsSender.Instance.SendEvent("deleteTarget", parameters);
    }

    public override void Load(AnchoringTarget target)
    {
        Clean();
        base.Load(target);
    }

    public override void Clean()
    {
        base.Clean();
        foreach (Transform child in transform)
        {
            Destroy(child.gameObject);
        }
        UnLoad();
        HasDispose = true;
    }

    private void OnFinishSave(ResponseHelper helper)
    {
        isError = false;
        isUpdating = false;
        if (!isError) SetIsEditedAndOppositeIsSaved(false);
        Debug.Log(helper.Text);
        Load(target);
    }

    void NotifySaveError(string errorMessage)
    {
        Debug.LogError(errorMessage);
        isError = true;
        isUpdating = false;
    }

    private void OnFinishLoad(ResponseHelper helper)
    {
        Debug.Log(helper.Text);
    }

    private void OnFinishRemove(ResponseHelper helper)
    {
        Debug.Log(helper.Text);
        Destroy(this.gameObject);
    }

    public AnchoringTarget GetTarget() => target;
    }
}
