using _Core;
using Seayoo.ComboSDK.Windows.Account.Net.v1;
using Seayoo.ComboSDK.Windows.Account.Model.VO;
using _Combo;
using _Combo.Events;
using Seayoo.ComboSDK.Windows.TapTap;
using System.Collections.Generic;

namespace Seayoo.ComboSDK.Windows.Account.View
{
    public class SeayooAccountViewMediator : Mediator
    {
        public SeayooAccountViewMediator(object viewComponent) : base(viewComponent)
        {
            EventSystem.Register(this);
        }

        public override void OnRegister()
        {
            accountView.OnCreate += OnCreate;
            Log.I("SeayooAccountViewMediator.OnRegister");
        }

        public void OnCreate()
        {
            var users = UserHistoryManager.Instance.GetUserHistories();
            var needAutoLogin = SeayooAccountManager.GetInstance().GetAutoLoginEnabled();

            if (needAutoLogin)
            {
                AutoLogin();
                return;
            }

            var needAutoLoginInTaptap = TapTapManager.GetInstance().GetAutoLoginEnabled();
            if (needAutoLoginInTaptap)
            {
                TapTapManager.GetInstance().AutoLogin((result)=>
                {
                    if (!result)
                    {
                        GoToLoginView(users);
                        return;
                    }
                });
                ShowLoginViewCommand.Invoke();
                return;
            }

            GoToLoginView(users);
        }

        private void GoToLoginView(List<Model.User> users)
        {
            if (users.Count == 0)
            {
                GoToViewCommand.Invoke(new GoToViewCommand
                {
                    viewType = SeayooAccountViewType.PHONE
                });
            }
            else
            {
                GoToViewCommand.Invoke(new GoToViewCommand
                {
                    viewType = SeayooAccountViewType.TOKEN
                });

            }
        }

        public override void OnRemove()
        {
            accountView.OnCreate -= OnCreate;
            EventSystem.UnRegister(this);
            Log.I("SeayooAccountViewMediator.OnRemove");
        }

        public void AutoLogin()
        {
            var user = SeayooAccountManager.GetInstance().GetAutoLoginUser();
            TokenLoginCommand.Invoke(new TokenLoginCommand
            {
                userId = user.userId,
                token = user.token
            });
        }

        [EventSystem.BindEvent]
        public void GetLoginOptions(GetLoginOptionsCommand action)
        {
            Log.I("SeayooAccountViewMediator.GetLoginOptions");
            UIController.Instance.ShowLoading(0.5f);
            AccountClient.GetLoginOptions(action.account, res =>
            {
                action.OnSuccess.Invoke(res.Data);
            }, (err) =>
            {
                action.OnFail.Invoke(err);
            });
        }

        [EventSystem.BindEvent]
        public void CreateCaptcha(CreateCaptchaCommand action)
        {
            Log.I("SeayooAccountViewMediator.CreateCaptchaCommand");
            UIController.Instance.ShowLoading(0.5f);
            AccountClient.CreateCaptcha(action.account, action.action, resp =>
            {
                action.OnSuccess.Invoke(resp.Data);
            }, () => action.OnFail.Invoke());
        }

        [EventSystem.BindEvent]
        public void CreateLoginOTP(CreateLoginOTPCommand action)
        {
            Log.I("SeayooAccountViewMediator.CreateLoginOTP");
            UIController.Instance.ShowLoading();
            AccountClient.CreateLoginOTP(action.mobile, action.captchaId, resp =>
            {
                action.OnSuccess.Invoke(resp.Data.action);
            }, () => action.OnFail.Invoke(), action.captchaResult);
        }

        [EventSystem.BindEvent]
        public void DeleteUserHistory(DeleteUserHistoryCommand action)
        {
            Log.I("SeayooAccountViewMediator.DeleteUserHistory");
            SeayooAccountManager.GetInstance().Logout(action.userId);
            var users = UserHistoryManager.Instance.GetUserHistories();

            if (users.Count == 0)
            {
                GoToViewCommand.Invoke(new GoToViewCommand
                {
                    viewType = SeayooAccountViewType.PHONE
                });
            }
            else
            {
                GoToViewCommand.Invoke(new GoToViewCommand
                {
                    viewType = SeayooAccountViewType.TOKEN
                });
            }

            UserHistoryManager.Instance.SetUserHistories(users);
        }

        [EventSystem.BindEvent]
        public void LoginWithOTP(PhoneLoginCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.LoginWithOTP(new Model.Net.LoginWithOTPRequest()
            {
                mobile = action.mobile,
                otp = action.otp,
                action = action.action
            }, resp =>
            {
                UIController.Instance.HideLoading();
                if (string.IsNullOrEmpty(resp.Data.user.token) && resp.Data.user.status == "deleting")
                {
                    DeteleAccountDialog();
                    return;
                }
                SeayooAccountManager.GetInstance().Login(new Model.User()
                {
                    userId = resp.Data.user.userId,
                    token = resp.Data.user.token,
                    mobile = resp.Data.user.mobile
                }, resp.Data.realNameRequired);
                if (resp.Data.realNameRequired)
                {
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.REALNAME,
                        vo = new RealNameVO
                        {
                            userId = resp.Data.user.userId,
                            token = resp.Data.user.token,
                        },
                    });
                }
                else
                {
                    CloseWindowCommand.Invoke(new CloseWindowCommand
                    {
                        userCancel = false,
                    });
                }
            }, () =>
            {
                UIController.Instance.HideLoading();
                RefreshViewCommand.Invoke();
            });
        }

        [EventSystem.BindEvent]
        public void LoginWithPassword(PasswordLoginCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.LoginWithPassword(new Model.Net.LoginWithPasswordRequest()
            {
                username = action.username,
                password = action.password,
                encrypted = action.encrypted,
                captchaId = action.captchaId,
                captchaResult = action.captchaResult
            }, resp =>
            {
                if (string.IsNullOrEmpty(resp.Data.user.token) && resp.Data.user.status == "deleting")
                {
                    UIController.Instance.HideLoading();
                    DeteleAccountDialog();
                    return;
                }
                if (resp.Data.deviceGrantRequired)
                {
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.GRANT,
                        vo = new PasswordLoginVO
                        {
                            mobile = resp.Data.user.mobile,
                            deviceGrantTicket = resp.Data.deviceGrantTicket,
                            phoneNumber = action.username
                        }
                    });
                    return;
                }
                UIController.Instance.HideLoading();
                SeayooAccountManager.GetInstance().PasswordLogin(new Model.User()
                {
                    userId = resp.Data.user.userId,
                    token = resp.Data.user.token,
                    mobile = resp.Data.user.mobile
                }, resp.Data.deviceGrantRequired, resp.Data.realNameRequired);
                if (resp.Data.realNameRequired)
                {
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.REALNAME,
                        vo = new RealNameVO
                        {
                            userId = resp.Data.user.userId,
                            token = resp.Data.user.token,
                        },
                    });
                    return;
                }
                if (!resp.Data.deviceGrantRequired && !resp.Data.realNameRequired)
                {
                    CloseWindowCommand.Invoke(new CloseWindowCommand
                    {
                        userCancel = false,
                    });
                }
            }, () =>
            {
                UIController.Instance.HideLoading();
                RefreshViewCommand.Invoke();
            });
        }

        [EventSystem.BindEvent]
        public void CreateDeviceGrantOTP(CreateDeviceGrantOTPCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            Log.I("SeayooAccountViewMediator.CreateDeviceGrantOTP");
            AccountClient.CreateDeviceGrantOTP(new Model.Net.CreateDeviceGrantOTPRequest()
            {
                ticket = action.ticket
            }, resp =>
            {
                action.OnSuccess.Invoke(resp.Data.mobile);
            }, (error) =>
            {
                action.OnFail.Invoke();
                if (error != null && error.error == "invalid_ticket")
                {
                    RefreshViewCommand.Invoke();
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.PHONE
                    });
                }
            }
            );
        }

        [EventSystem.BindEvent]
        public void GrantDeviceWithOTP(GrantDeviceWithOTPCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.GrantDeviceWithOTP(new Model.Net.GrantDeviceWithOTPRequest()
            {
                ticket = action.ticket,
                otp = action.otp
            }, resp =>
            {
                UIController.Instance.HideLoading();
                if (resp.IsSuccess)
                {
                    TokenLoginCommand.Invoke(new TokenLoginCommand
                    {
                        userId = resp.Data.userId,
                        token = resp.Data.token,
                    });
                }
            }, (error) =>
            {
                UIController.Instance.HideLoading();
                if (error != null && error.error == "invalid_ticket")
                {
                    RefreshViewCommand.Invoke();
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.PHONE
                    });
                }
            });
        }

        [EventSystem.BindEvent]
        public void VerifyLoginToken(TokenLoginCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.VerifyLoginToken(new Model.Net.VerifyLoginTokenRequest()
            {
                userId = action.userId,
                token = action.token
            }, resp =>
            {
                UIController.Instance.HideLoading();
                if (string.IsNullOrEmpty(resp.Data.user.token) && resp.Data.user.status == "deleting")
                {
                    DeteleAccountDialog();
                    return;
                }
                SeayooAccountManager.GetInstance().Login(new Model.User()
                {
                    userId = resp.Data.user.userId,
                    token = resp.Data.user.token,
                    mobile = resp.Data.user.mobile
                }, resp.Data.realNameRequired, null);
                if (resp.Data.realNameRequired)
                {
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.REALNAME,
                        vo = new RealNameVO
                        {
                            userId = resp.Data.user.userId,
                            token = resp.Data.user.token,
                        }
                    });
                }
                else
                {
                    CloseWindowCommand.Invoke(new CloseWindowCommand
                    {
                        userCancel = false,
                    });
                }
            }, (error, userId) =>
            {
                UIController.Instance.HideLoading();
                if (error != null && error.error == "invalid_token")
                {
                    DeleteUserHistoryCommand.Invoke(new DeleteUserHistoryCommand { userId = userId });
                    SeayooAccountManager.GetInstance().SetAutoLoginEnabled(false);
                    RefreshViewCommand.Invoke();
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.PHONE
                    });
                    return;
                }
                RefreshViewCommand.Invoke();
            });
        }

        [EventSystem.BindEvent]
        public void AuthRealName(RealNameCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.AuthRealName(new Model.Net.AuthRealNameRequest()
            {
                userId = action.userId,
                token = action.token,
                realName = action.realName,
                identityCard = action.identityCard,
                encrypted = action.encrypted,
            }, (data) =>
            {
                UIController.Instance.HideLoading();
                if (string.IsNullOrEmpty(data.Data.user.token) && data.Data.user.status == "deleting")
                {
                    DeteleAccountDialog();
                    return;
                }
                SeayooAccountManager.GetInstance().Login(new Model.User()
                {
                    userId = data.Data.user.userId,
                    token = data.Data.user.token,
                    mobile = data.Data.user.mobile
                }, false);
                CloseWindowCommand.Invoke(new CloseWindowCommand
                {
                    userCancel = false,
                });
            }, () =>
            {
                UIController.Instance.HideLoading();
                RefreshViewCommand.Invoke();
            });
        }

        [EventSystem.BindEvent]
        public void AuthRealName(LinkRealNameCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.AuthRealName(new Model.Net.AuthRealNameRequest()
            {
                userId = action.userId,
                token = action.token,
                realName = action.realName,
                identityCard = action.identityCard,
                encrypted = action.encrypted,
            }, (data) =>
            {
                UIController.Instance.HideLoading();
                if (string.IsNullOrEmpty(data.Data.user.token) && data.Data.user.status == "deleting")
                {
                    DeteleAccountDialog();
                    return;
                }
                SeayooAccountManager.GetInstance().Login(new Model.User()
                {
                    userId = data.Data.user.userId,
                    token = data.Data.user.token,
                    mobile = data.Data.user.mobile
                }, false, action.linkCredential);
                CloseWindowCommand.Invoke(new CloseWindowCommand
                {
                    userCancel = false,
                });
            }, () =>
            {
                UIController.Instance.HideLoading();
                RefreshViewCommand.Invoke();
            });
        }

        [EventSystem.BindEvent]
        public void LoginCancel(CloseWindowCommand action)
        {
            if (!action.userCancel)
                return;

            LoginCancelEvent.Invoke();
        }

        [EventSystem.BindEvent]
        public void LinkIdentity(LinkIdentityCommand action)
        {
            UIController.Instance.ShowLoading(0.3f);
            AccountClient.LoginWithOTP(new Model.Net.LoginWithOTPRequest()
            {
                mobile = action.mobile,
                otp = action.otp,
                action = action.action
            }, resp =>
            {
                UIController.Instance.HideLoading();
                if (string.IsNullOrEmpty(resp.Data.user.token) && resp.Data.user.status == "deleting")
                {
                    DeteleAccountDialog();
                    return;
                }
                SeayooAccountManager.GetInstance().Login(new Model.User()
                {
                    userId = resp.Data.user.userId,
                    token = resp.Data.user.token,
                    mobile = resp.Data.user.mobile
                }, resp.Data.realNameRequired, action.credential);
                if (resp.Data.realNameRequired)
                {
                    GoToViewCommand.Invoke(new GoToViewCommand
                    {
                        viewType = SeayooAccountViewType.LINK_REALNAME,
                        vo = new LinkRealNameVO
                        {
                            userId = resp.Data.user.userId,
                            token = resp.Data.user.token,
                            linkCredential = action.credential
                        },
                    });
                }
                else
                {
                    CloseWindowCommand.Invoke(new CloseWindowCommand
                    {
                        userCancel = false,
                    });
                }
            }, () =>
            {
                UIController.Instance.HideLoading();
                RefreshViewCommand.Invoke();
            }, action.credential);
        }

        public SeayooAccountView accountView
        {
            get
            {
                return ViewComponent as SeayooAccountView;
            }
        }

        private void DeteleAccountDialog()
        {
            CloseWindowCommand.Invoke(new CloseWindowCommand
            {
                userCancel = false
            });
            UIController.Instance.ShowAlertView(
                I18n.T("login_account_deleting_dialog_title"),
                I18n.T("login_account_deleting_dialog_text"),
                UnityEngine.TextAnchor.UpperLeft,
                I18n.T("switch_account_button"),
                I18n.T("open_seayoo_account_website_button"),
                () =>
                {
                    SeayooAccount.Instance.Logout();
                    SeayooAccount.Instance.Login();
                },
                () =>
                {
#if UNITY_STANDALONE
                    UIController.Instance.ShowWebView(GlobalParameters.Instance.SeayooAccountWebsiteUrl, WebViewType.General, 100, 100, true, onClose: () =>
                    {
                        SeayooAccount.Instance.Login();
                    });
#endif
                }
            );
        }
    }
}
