using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices.Protocols;
using System.Net;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using static DbTableClass;

namespace ad_login.Controllers
{
    [EnableCors("any")]
    [Route("adApi")]
  
    public class AdApiController : ControllerBase
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly PasswordManagementService _passwordManagement;
        private readonly string _ldapServer;
        private readonly string _domain;
        private readonly string _baseDn;

        public AdApiController(IHttpContextAccessor httpContextAccessor, IWebHostEnvironment webHostEnvironment, PasswordManagementService passwordManagement, IOptions<LdapSettings> ldapSettings)
        {
            this._httpContextAccessor = httpContextAccessor;
            this._hostingEnvironment = webHostEnvironment;
            this._passwordManagement = passwordManagement;
            this._ldapServer = ldapSettings.Value.Server;
            this._domain = ldapSettings.Value.Domain;
            this._baseDn = ldapSettings.Value.BaseDn;
        }

        [EnableCors("any")]
        [Route("aduserList")]
        [SupportedOSPlatform("windows")]
        public ActionResult AduserList(IFormCollection obj) {

            Result ret = new Result();
            List<String> expiringUsers = [];

            DirectoryEntry entry = new DirectoryEntry($"LDAP://{_ldapServer}/{_baseDn}", GlobalClass.appsettings("LdapSettings:User"), GlobalClass.appsettings("LdapSettings:Password")); // 使用 LDAP 伺服器和基礎 DN 建立 DirectoryEntry 物件。
            DirectorySearcher mySearcher = new DirectorySearcher(entry);
            mySearcher.Filter = "(&(objectCategory=person)(objectClass=user))"; // 篩選有「上次密碼設定時間」、「Mail」的「使用者」。
              // 電子郵件

            foreach (SearchResult result in mySearcher.FindAll())
            {
                string userSAMAccountName = result.Properties["sAMAccountName"][0].ToString() ?? string.Empty; // AD 帳號
                string userDisplayName = "";
                string userMail = "";
                if (result.Properties["displayName"].Count > 0)
                    userDisplayName = result.Properties["displayName"][0].ToString();
                else
                    userDisplayName = userSAMAccountName;       // 顯示名稱

                if (result.Properties["mail"].Count > 0) {
                   userMail = result.Properties["mail"][0].ToString() ?? string.Empty;
                }

                int flags = (int)result.Properties["userAccountControl"][0];
                string expiringUsersInfo = $"{userSAMAccountName};{userDisplayName};{userMail}";

                adUser adUser = new adUser
                {
                    userAccount = userSAMAccountName,
                    userDisplayName = userDisplayName,
                    userMail = userMail
                };

                if (!Convert.ToBoolean(flags & 0x0002) && (userMail != "")) {
                    ret.data.Add(adUser); // 如果帳號沒有被停用，且有電子郵件，就加入結果列表。
                }
            }

            ret.ret = "yes";

            return Content(JsonConvert.SerializeObject(ret), "application/json;charset=utf-8");
        }

        public class Result
        {
            public string ret = "no";
            public string err_code = "0000";
            public string message = "";
            public List<adUser> data = new List<adUser>();
        }

        public class adUser
        {
            public string userAccount { get; set; } = string.Empty; // AD 帳號
            public string userDisplayName { get; set; } = string.Empty; // 顯示名稱
            public string userMail { get; set; } = string.Empty; // 電子郵件
        }

    }
}
