using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using TABS.MailCarrier.StgBase;
using TABS.MailCarrier.WebSDK;
using TABS.MailCarrier.WebSDK.User;
using TABS.MailCarrier.AuxLib.GoogleOTP;

public partial class Logon : System.Web.UI.Page
{
    protected string _pwdValue = "";

    protected override void InitializeCulture()
    {
        base.InitializeCulture();
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        WebUtil.SetMcCommonCss3(Page.Header);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (AppSetting.AllowMobileDeviceOnly && !BrowserDetector.IsMobileDevice(Request))
        {
            Response.Redirect("~/Error.aspx?code=21", true);
            return;
        }

        if (!Request.IsSecureConnection && AppSetting.RedirectHttps)
        {
            string httpsUri = Request.Url.AbsoluteUri.Replace("http://", "https://");
            Response.Redirect(httpsUri, true);
            return;
        }

        AppSetting.TitleInfo titleInfo = AppSetting.GetTitleInfo(Request);
        Page.Title = titleInfo.Title;
        if (!IsPostBack)
        {
            // 로그인 폼 페이지에서 SignOut을 호출해서 사용자를 로그 아웃시킨다.
            FormsAuthentication.SignOut();
            // 로그인 세션을 제거한다.
            WebUser.ExpireSession();
            
            if (AppSetting.UseSafeAddress4Download && Request.Cookies["UserInfo"] != null)
            {
                // <allow users="*"/>가 정의된 페이지에서 로그인 여부를 확인하기 위해 UserInfo 쿠키를 제거한다.
                HttpCookie cookie = new HttpCookie("UserInfo"); // 과거 날짜로 설정한 후 덮어쓰기
                cookie.Expires = DateTime.Now.AddDays(-1);
                Response.Cookies.Add(cookie);
            }

            TitleLabel.Text = titleInfo.Title;
            if (Request.Cookies["SaveLoginID"] != null)
            {
                id.Value = Server.HtmlEncode(Request.Cookies["SaveLoginID"].Value);
                SaveIDCheckBox.Checked = true;
            }
            else
            {
                id.Focus();
            }

            // 기본 언어 선택            
            string defLang = GetDefaultLanguage();
            foreach (ListItem item in LanguageList.Items)
            {
                if (item.Value == defLang)
                {
                    item.Selected = true;
                    break;
                }
            }

            string clientIp;
            clientIp = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (clientIp == null) clientIp = Request.UserHostAddress;
            if (AppSetting.UseOTP && !AppSetting.ExistInOtpFreeZone(clientIp))
            {
                BootstrapUtil.CollapseControl(otpPanel, false);
            }

            if (AppSetting.UseTimeZone)
            {
                BootstrapUtil.CollapseControl(timeZonePanel, false);
                // 표준 시간대 로딩
                LoadTimeZoneList("ko");
                // 표준시간대 기본값 선택
                string defTimeZone = (Request.Cookies["DefaultTimeZone"] != null) ? Request.Cookies["DefaultTimeZone"].Value : "";
                if (defTimeZone == "") defTimeZone = TimeZoneInfo.Local.Id;     // 쿠키에 표준시간대 기본값이 없을 경우 서버 타임존을 선택
                foreach (ListItem item in TimeZoneList.Items)
                {
                    if (item.Value == defTimeZone) item.Selected = true;
                }
            }

            if (Request.Cookies["SaveLoginPwd"] != null)
            {
                _pwdValue = Server.HtmlEncode(Request.Cookies["SaveLoginPwd"].Value);
                SavePwdCheckBox.Checked = true;
            }

            version.Value = string.Format("Web:{0}, Scheme:{1}, ClientIP:{2}", AppSetting.WebAppVersion, GlobalConfig.SchemaVersion, clientIp);
        }

        AlertBrowser.Visible = false;       
    }

    protected void LogonButton_Click(object sender, EventArgs e)
    {
        string account = id.Value;
        string clientIp;
        clientIp = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
        if (clientIp == null) clientIp = Request.UserHostAddress;

        AppSetting.TitleInfo titleInfo = AppSetting.GetTitleInfo(Request);
        if (!titleInfo.IsAcceptedIP(clientIp))
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg13").ToString();            
            return;
        }
        if (titleInfo.AuthDomain != "")
        {
            int inx = 0;
            if ((inx = account.IndexOf('@')) > 0)
            {
                account = account.Substring(0, inx);
            }
            account += "@" + titleInfo.AuthDomain;
        }

        string password = Request["password"];
        DomainUser user = new DomainUser();
        DomainUser.LogonErrorCode errCode =
            (GlobalConfig.UseOnewayPassword) ?
                user.Logon(account, password, clientIp, false, AppSetting.ControlLoginSeparately ? Mcsp.UserServiceFlag.WebMobile : Mcsp.UserServiceFlag.WebMail) :
                user.Logon(account, password, clientIp, AppSetting.UseEncryptPassword, AppSetting.ControlLoginSeparately ? Mcsp.UserServiceFlag.WebMobile : Mcsp.UserServiceFlag.WebMail);

        if (errCode == DomainUser.LogonErrorCode.Success)
        {
            string domainUserId = user.DomainUserID.ToString();

            // OTP 키가 존재할 경우 OTP 인증을 검사한다.
            if (AppSetting.UseOTP)
            {
                // 접속 IP가 OTPFreeZone에 포함되어 있지 않은 경우만 OTP 인증이 필요하다.
                if (!AppSetting.ExistInOtpFreeZone(clientIp))
                {
                    if (user.OtpSecretKey.Length > 0)
                    {
                        int otpNumber = 0;
                        int.TryParse(Request["otpPassword"], out otpNumber);
                        OneTimePassword otp = new OneTimePassword(user.OtpSecretKey);
                        if (!otp.IsValidPassword(otpNumber))
                        {
                            ErrorLabel.Text = GetLocalResourceObject("Msg08").ToString(); ;
                            otpPassword.Focus();
                            return;
                        }
                    }
                    else if (AppSetting.ForceUseOfOTP)
                    {
                        ErrorLabel.Text = GetLocalResourceObject("Msg14").ToString(); ;
                        otpPassword.Focus();
                        return;
                    }
                }
            }

            if (SaveIDCheckBox.Checked)
            {
                Response.Cookies["SaveLoginID"].Value = user.MailAddress;
                Response.Cookies["SaveLoginID"].Expires = DateTime.Now.AddDays(30);
            }
            else
            {
                Response.Cookies["SaveLoginID"].Expires = DateTime.Now.AddDays(-1);
            }
            if (SavePwdCheckBox.Checked)
            {
                Response.Cookies["SaveLoginPwd"].Value = password;
                Response.Cookies["SaveLoginPwd"].Expires = DateTime.Now.AddDays(30);
            }
            else
            {
                Response.Cookies["SaveLoginPwd"].Expires = DateTime.Now.AddDays(-1);
            }

            // 기본 언어를 쿠키에 저장한다.
            Response.Cookies["DefaultLanguage"].Value = LanguageList.SelectedValue;
            Response.Cookies["DefaultLanguage"].Expires = DateTime.Now.AddDays(3650);

            // 기본 타임존을 쿠키에 저장한다.
            if (AppSetting.UseTimeZone)
            {
                Response.Cookies["DefaultTimeZone"].Value = TimeZoneList.SelectedValue;
                Response.Cookies["DefaultTimeZone"].Expires = DateTime.Now.AddDays(3650);
            }
            else
            {
                Response.Cookies["DefaultTimeZone"].Value = "";
            }

            if (AppSetting.UseSafeAddress4Download)
            {
                // <allow users="*"/>가 정의된 페이지에서 로그인 여부를 확인하기 위해 UserInfo 쿠키를 사용한다.
                HttpCookie userCookie = new HttpCookie("UserInfo");
                userCookie["Account"] = user.Account;
                userCookie.Expires = DateTime.Now.AddHours(6);
                Response.Cookies.Add(userCookie);
            }

            string returnUrl = Request.QueryString["ReturnUrl"];
            if (returnUrl != null && returnUrl.IndexOf("webpush") > 0)
            {
                // web push에서 전달된 요청은 ReturnUrl대로 처리
                FormsAuthentication.RedirectFromLoginPage(domainUserId, false);
            }
            else
            {
                // 로그인 후 ReturnURL과 상관없이 무조건 FormsAuthentication.DefaultUrl로 이동한다.
                //  - 모바일에서는 인증 타임아웃 -> 재로그인 -> DefaultUrl로 이동
                FormsAuthentication.SetAuthCookie(domainUserId, false);
                Response.Redirect(FormsAuthentication.DefaultUrl);
            }
        }
        else if (errCode == DomainUser.LogonErrorCode.InvalidLicense)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg01").ToString();
        }
        else if (errCode == DomainUser.LogonErrorCode.NoPermitUser)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg07").ToString();
        }
        else if (errCode == DomainUser.LogonErrorCode.NoPermitWebAccess)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg07").ToString();
        }
        else if (errCode == DomainUser.LogonErrorCode.InvalidEmail)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg07").ToString();
            id.Focus();
        }
        else if (errCode == DomainUser.LogonErrorCode.InvalidPassword)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg07").ToString();
            id.Focus();
        }
        else if (errCode == DomainUser.LogonErrorCode.NotExistUser)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg07").ToString();
            id.Focus();
        }
        else if (errCode == DomainUser.LogonErrorCode.InvalidSchemaVersion)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg09").ToString();
            id.Focus();
        }
        else if (errCode == DomainUser.LogonErrorCode.NonDomesticIP)
        {
            ErrorLabel.Text = string.Format("{0}({1})", GetLocalResourceObject("Msg10").ToString(), clientIp);
        }
        else if (errCode == DomainUser.LogonErrorCode.AccountIpLocked)
        {
            ErrorLabel.Text = GetLocalResourceObject("Msg11").ToString();
        }

        if (errCode != DomainUser.LogonErrorCode.Success)
        {
            Response.Cookies["SaveLoginID"].Expires = DateTime.Now.AddDays(-1);
            Response.Cookies["SaveLoginPwd"].Expires = DateTime.Now.AddDays(-1);
        }
    }

    /// <summary>
    /// 콤보박스에 기본 언어 선택
    /// - 쿠키에 지정되어 있을 경우 그 값을 기본으로 선택
    /// - 쿠키에 없을 경우 브라우저 값을 기본으로 선택
    /// </summary>
    /// <returns></returns>
    private string GetDefaultLanguage()
    {
        string defLang = "";
        if (Request.Cookies["DefaultLanguage"] != null)
        {
            defLang = Request.Cookies["DefaultLanguage"].Value;
        }
        if (defLang == "")
        {
            if (Thread.CurrentThread.CurrentUICulture.Name.IndexOf("ko") != -1)
                defLang = "ko";
            else
                defLang = "en";
        }
        return defLang;
    }

    private void LoadTimeZoneList(string defLang)
    {
        DateTimeFormatInfo dateFormats = CultureInfo.CurrentCulture.DateTimeFormat;
        ReadOnlyCollection<TimeZoneInfo> timeZones = TimeZoneInfo.GetSystemTimeZones();

        if (defLang == "ko")
        {
            foreach (TimeZoneInfo timeZone in timeZones)
            {
                TimeZoneList.Items.Add(new ListItem(timeZone.DisplayName, timeZone.Id));
            }
        }
        else
        {
            foreach (TimeZoneInfo timeZone in timeZones)
            {
                int zoneLen = timeZone.DisplayName.IndexOf(")");
                string timeZoneName = timeZone.DisplayName.Substring(0, zoneLen + 1);
                TimeZoneList.Items.Add(new ListItem(timeZoneName + " " + timeZone.Id, timeZone.Id));
            }
        }
    }
}