using System;
using UnityEngine;
using UnityEngine.Serialization;

namespace MajacloudSdk
{
    /// <summary>
    /// Project connection settings. Created by Tools ▸ Majacloud ▸ Setup at
    /// Assets/Resources/MajacloudSettings.asset and loaded automatically.
    /// </summary>
    [CreateAssetMenu(fileName = "MajacloudSettings", menuName = "Majacloud/Settings")]
    public sealed class MajacloudSettings : ScriptableObject
    {
        public const string ResourceName = "MajacloudSettings";

        [Header("Connection")]
        [Tooltip("Base URL of your MAJACLOUD install, e.g. https://cloud.example.com or http://localhost/MAJACLOUD")]
        [SerializeField] private string baseUrl = "http://localhost/MAJACLOUD";
        [Tooltip("Project ID from the dashboard")]
        [SerializeField] private string projectId;
        [Tooltip("Public client key (pk_live_...). Safe to ship in builds; never put the server secret here.")]
        [SerializeField] private string clientKey;
        [FormerlySerializedAs("secretKey")]
        [SerializeField, HideInInspector] private string legacySecretKey;

        [Header("Project (filled by Test connection)")]
        [SerializeField] private string projectName;
        [SerializeField] private string plan;
        [TextArea(2, 4)]
        [Tooltip("RSA public key used to verify Remote Config. Stored when you test the connection.")]
        [SerializeField] private string configPublicKeyXml;
        [SerializeField] private string configKeyId;

        [Header("Behaviour")]
        [Range(3, 60)] [SerializeField] private int requestTimeoutSeconds = 10;
        [Range(0, 5)] [SerializeField] private int maxRetries = 2;
        [SerializeField] private bool fetchConfigOnInitialize = true;
        [Tooltip("Development only: accept Remote Config that cannot be verified (unsigned server or no public key) when the Base URL is localhost. Signed configs are always verified.")]
        [SerializeField] private bool allowUnsignedConfigOnLocalhost;
        [SerializeField] private int configCacheMaxBytes = 512 * 1024;
        [SerializeField] private MajacloudLogLevel logLevel = MajacloudLogLevel.Warning;
        [SerializeField] private bool logRequests;

        public string BaseUrl => (baseUrl ?? string.Empty).Trim().TrimEnd('/');
        public string ProjectId => (projectId ?? string.Empty).Trim();
        public string ClientKey => (clientKey ?? string.Empty).Trim();
        public string ProjectName => projectName ?? string.Empty;
        public string Plan => plan ?? string.Empty;
        public string ConfigPublicKeyXml => (configPublicKeyXml ?? string.Empty).Trim();
        public string ConfigKeyId => configKeyId ?? string.Empty;
        public int RequestTimeoutSeconds => Mathf.Clamp(requestTimeoutSeconds, 3, 60);
        public int MaxRetries => Mathf.Clamp(maxRetries, 0, 5);
        public bool FetchConfigOnInitialize => fetchConfigOnInitialize;
        public bool AllowUnsignedConfigOnLocalhost => allowUnsignedConfigOnLocalhost;
        public int ConfigCacheMaxBytes => Mathf.Max(16 * 1024, configCacheMaxBytes);
        public MajacloudLogLevel LogLevel => logLevel;
        public bool LogRequests => logRequests;
        public bool HasLegacySecretKey => !string.IsNullOrEmpty(legacySecretKey);
        public bool HasConfigPublicKey => !string.IsNullOrEmpty(ConfigPublicKeyXml);
        public bool IsConfigured => !string.IsNullOrEmpty(BaseUrl) && !string.IsNullOrEmpty(ProjectId) && !string.IsNullOrEmpty(ClientKey);

        public bool IsLocalhost
        {
            get
            {
                if (!Uri.TryCreate(BaseUrl, UriKind.Absolute, out var uri)) return false;
                return uri.IsLoopback || uri.Host == "localhost";
            }
        }

        public void Configure(string apiBaseUrl, string apiProjectId, string apiClientKey)
        {
            baseUrl = (apiBaseUrl ?? string.Empty).Trim().TrimEnd('/');
            projectId = (apiProjectId ?? string.Empty).Trim();
            clientKey = (apiClientKey ?? string.Empty).Trim();
            legacySecretKey = null;
        }

        public void SetProjectInfo(string name, string planType, string publicKeyXml, string keyId)
        {
            projectName = name ?? string.Empty;
            plan = planType ?? string.Empty;
            if (!string.IsNullOrEmpty(publicKeyXml)) configPublicKeyXml = publicKeyXml.Trim();
            if (!string.IsNullOrEmpty(keyId)) configKeyId = keyId;
        }

        /// <summary>Validate the asset; the error message is suitable for the Console.</summary>
        public bool TryValidate(out string error)
        {
            if (string.IsNullOrEmpty(BaseUrl) || string.IsNullOrEmpty(ProjectId))
            {
                error = "MajacloudSettings is missing the Base URL or Project ID. Open Tools ▸ Majacloud ▸ Setup.";
                return false;
            }
            if (HasLegacySecretKey)
            {
                error = "MajacloudSettings still contains a server Secret Key. Remove it and use the public Client Key.";
                return false;
            }
            if (string.IsNullOrEmpty(ClientKey))
            {
                error = "MajacloudSettings is missing the Client Key (pk_live_...).";
                return false;
            }
            if (!Uri.TryCreate(BaseUrl, UriKind.Absolute, out var uri) || (uri.Scheme != "http" && uri.Scheme != "https"))
            {
                error = "MajacloudSettings Base URL must start with http:// or https://.";
                return false;
            }
            if (uri.Scheme == "http" && !uri.IsLoopback && uri.Host != "localhost")
            {
                error = "Use https:// for any server other than localhost.";
                return false;
            }
            error = null;
            return true;
        }
    }
}
