using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace AudioWallpaper.SSO {

    public interface ITokenStore {
        void Save(string tokenName, string token);
        string? Get(string tokenName);
        void Clear(string tokenName);
    }
    public class EncryptedFileTokenStore : ITokenStore {
        private readonly string _storagePath;
        private readonly object _lock = new();

        public EncryptedFileTokenStore(string storageDirectory) {
            _storagePath = storageDirectory;
            Directory.CreateDirectory(_storagePath);
        }

        private string GetTokenFilePath(string tokenName) =>
            Path.Combine(_storagePath, $"{tokenName}.token");

        public void Save(string tokenName, string token) {
            var data = Encoding.UTF8.GetBytes(token);
            var encrypted = ProtectedData.Protect(data, null, DataProtectionScope.CurrentUser);

            lock (_lock) {
                File.WriteAllBytes(GetTokenFilePath(tokenName), encrypted);
            }
        }

        public string? Get(string tokenName) {
            var path = GetTokenFilePath(tokenName);
            if (!File.Exists(path))
                return null;

            try {
                lock (_lock) {
                    var encrypted = File.ReadAllBytes(path);
                    var decrypted = ProtectedData.Unprotect(encrypted, null, DataProtectionScope.CurrentUser);
                    return Encoding.UTF8.GetString(decrypted);
                }
            } catch {
                return null; // 可选：记录日志
            }
        }

        public void Clear(string tokenName) {
            var path = GetTokenFilePath(tokenName);
            lock (_lock) {
                if (File.Exists(path))
                    File.Delete(path);
            }
        }
    }


    public class TokenManager {
        private readonly ITokenStore _store;


        private const string AccessTokenKey = "access_token";
        private const string RefreshTokenKey = "refresh_token";
        private const string IdTokenKey = "id_token";
        private const string LoginMetaKey = "login_state";

        public TokenManager(ITokenStore store) {
            _store = store ?? throw new ArgumentNullException(nameof(store));
        }

        // 保存 TokenSet
        public void SaveToken(TokenSet tokens) {
            SaveToken(tokens, null);
        }
        public void SaveToken(TokenSet tokens, UserInfoSet? userInfoSet) {
            if (tokens == null) throw new ArgumentNullException(nameof(tokens));

            if (string.IsNullOrWhiteSpace(tokens.AccessToken))
                throw new ArgumentException("Access token is required.");
            if (string.IsNullOrWhiteSpace(tokens.RefreshToken))
                throw new ArgumentException("Refresh token is required.");
            if (string.IsNullOrWhiteSpace(tokens.IdToken))
                throw new ArgumentException("ID token is required.");

            _store.Save(AccessTokenKey, tokens.AccessToken);
            _store.Save(RefreshTokenKey, tokens.RefreshToken);
            _store.Save(IdTokenKey, tokens.IdToken);
            if (userInfoSet != null) {

                LoginMeta loginMeta = new LoginMeta {
                    IsLoggedIn = true,
                    UserInfo = userInfoSet
                };
                SaveLoginMeta(loginMeta);
            }
        }
        public void SaveLoginMeta(LoginMeta? loginMeta) {
            if (loginMeta == null)
                throw new ArgumentNullException(nameof(loginMeta));

            string loginMetaJson = JsonSerializer.Serialize(loginMeta);
            _store.Save(LoginMetaKey, loginMetaJson);

        }

        // 保存单个 token
        public void SaveToken(string name, string token) {
            if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Token name is required.");
            if (string.IsNullOrWhiteSpace(token)) throw new ArgumentException("Token value is required.");

            _store.Save(name, token);
        }

        // 获取 TokenSet
        public TokenSet? GetToken() {
            var accessToken = _store.Get(AccessTokenKey);
            var refreshToken = _store.Get(RefreshTokenKey);
            var idToken = _store.Get(IdTokenKey);

            if (string.IsNullOrWhiteSpace(accessToken) && string.IsNullOrWhiteSpace(refreshToken) && string.IsNullOrWhiteSpace(idToken))
                return null;
            return new TokenSet(accessToken ?? string.Empty, refreshToken ?? string.Empty, idToken ?? string.Empty);
        }

        // 获取指定 token
        public string? GetToken(string name) {
            if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Token name is required.");
            return _store.Get(name);
        }

        // 获取登录状态
        public LoginMeta? GetLoginMeta() {
            var loginMetaJson = _store.Get(LoginMetaKey);
            if (string.IsNullOrWhiteSpace(loginMetaJson))
                return null;
            try {
                return JsonSerializer.Deserialize<LoginMeta>(loginMetaJson);
            } catch (JsonException) {
                return null; // 可选：记录日志
            }
        }

        // 清除全部 token
        public void ClearToken() {
            _store.Clear(AccessTokenKey);
            _store.Clear(RefreshTokenKey);
            _store.Clear(IdTokenKey);
            _store.Clear(LoginMetaKey);
        }

        // 清除指定 token
        public void ClearToken(string name) {
            if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("Token name is required.");
            _store.Clear(name);
        }
    }


}
