namespace Domain.Entities.Common
{
    public sealed class Config
    {
        public int ID { get; private set; }
        public DateTime LastUpdatedAt { get; private set; } = DateTime.UtcNow;
        public byte[] RowVersion { get; private set; } = [];
        public BasicConfig Basic { get; private set; } = new();
        public ImagesConfig Images { get; private set; } = new();
        public MetaConfig Meta { get; private set; } = new();
        public CompanyConfig Company { get; private set; } = new();
        public AccountConfig Account { get; private set; } = new();
        public EmailTemplateConfig EmailTemplate { get; private set; } = new();
        public ExternalApiConfig External { get; private set; } = new();
        public PaymentConfig Payment { get; private set; } = new();
        public CryptoConfig Crypto { get; private set; } = new();

        private Config() { }

        public static Config Create()
        {
            return new();
        }

        public void Update(
            BasicConfig basic,
            ImagesConfig images,
            MetaConfig meta,
            CompanyConfig company,
            AccountConfig account,
            EmailTemplateConfig emailTemplate,
            ExternalApiConfig external,
            PaymentConfig payment,
            CryptoConfig crypto
        ) {
            Basic = basic ?? throw new ArgumentNullException(nameof(basic));
            Images = images ?? throw new ArgumentNullException(nameof(images));
            Meta = meta ?? throw new ArgumentNullException(nameof(meta));
            Company = company ?? throw new ArgumentNullException(nameof(company));
            Account = account ?? throw new ArgumentNullException(nameof(account));
            EmailTemplate = emailTemplate ?? throw new ArgumentNullException(nameof(emailTemplate));
            External = external ?? throw new ArgumentNullException(nameof(external));
            Payment = payment ?? throw new ArgumentNullException(nameof(payment));
            Crypto = crypto ?? throw new ArgumentNullException(nameof(crypto));
            LastUpdatedAt = DateTime.UtcNow;
        }
    }

    #region Owned Groups

    // ==================================================
    // 기본 정보 (Basic)
    // ==================================================
    public sealed class BasicConfig
    {
        public string? SiteName { get; set; }
        public string? SiteURL { get; set; }
        public string? RootID { get; set; }
        public string? FromEmail { get; set; }
        public string? FromName { get; set; }
        public string? SmtpServer { get; set; }
        public int? SmtpPort { get; set; }
        public bool SmtpEnableSSL { get; set; }
        public string? SmtpUsername { get; set; }
        public string? SmtpPassword { get; set; }
        public string? AdminWhiteIPList { get; set; }
        public string? FrontWhiteIPList { get; set; }
        public string? BlockAlertTitle { get; set; }
        public string? BlockAlertContent { get; set; }
        public bool IsMaintenance { get; set; } = false;
        public string? MaintenanceContent { get; set; }
    }

    // ==================================================
    // 기본 이미지 (Images)
    // ==================================================
    public sealed class ImagesConfig
    {
        public string? Favicon { get; set; }
        public string? LogoSquare { get; set; }
        public string? LogoHorizontal { get; set; }
        public string? OgDefault { get; set; }
        public string? TwitterImage { get; set; }
        public string? AppleTouchIcon { get; set; }
        public string? AppIcon_192 { get; set; }
        public string? AppIcon_512 { get; set; }
    }

    // ==================================================
    // 메타 태그 (Meta)
    // ==================================================
    public sealed class MetaConfig
    {
        public string? Keywords { get; set; }
        public string? Description { get; set; }
        public string? Author { get; set; }
        public string? Viewport { get; set; }
        public string? ApplicationName { get; set; }
        public string? Generator { get; set; }
        public string? Robots { get; set; }
        public string? Adds { get; set; }
    }

    // ==================================================
    // 회사 정보 (Company)
    // ==================================================
    public sealed class CompanyConfig
    {
        public string? Name { get; set; }
        public string? RegNo { get; set; }
        public string? Address { get; set; }
        public string? ZipCode { get; set; }
        public string? Owner { get; set; }
        public string? Tel { get; set; }
        public string? Fax { get; set; }
        public string? RetailSaleNo { get; set; }
        public string? AddedSaleNo { get; set; }
        public string? Hosting { get; set; }
        public string? AdminName { get; set; }
        public string? AdminEmail { get; set; }
        public string? SiteUrl { get; set; }
        public string? BankCode { get; set; }
        public string? BankOwner { get; set; }
        public string? BankNumber { get; set; }
    }

    // ==================================================
    // 회원가입 설정 (Account)
    // ==================================================
    public sealed class AccountConfig
    {
        // 회원 가입 시
        public bool IsRegisterBlock { get; set; } = false;
        public bool IsRegisterEmailAuth { get; set; } = false;
        public ushort? PasswordMinLength { get; set; }
        public ushort? PasswordUppercaseLength { get; set; }
        public ushort? PasswordNumbersLength { get; set; }
        public ushort? PasswordSpecialcharsLength { get; set; }
        public string? DeniedEmailList { get; set; }
        public string? DeniedNameList { get; set; }

        // 회원 수정 시
        public ushort? ChangeEmailDay { get; set; }
        public ushort? ChangeNameDay { get; set; }
        public ushort? ChangeSummaryDay { get; set; }
        public ushort? ChangeIntroDay { get; set; }
        public ushort? ChangePasswordDay { get; set; }

        // 로그인 시
        public bool IsLoginEmailVerifiedOnly { get; set; } = false;
        public ushort? MaxLoginTryCount { get; set; }
        public ushort? MaxLoginTryLimitSecond { get; set; }
    }

    // ==================================================
    // 알림 발송 양식 - 이메일 (EmailTemplate)
    // ==================================================
    public sealed class EmailTemplateConfig
    {
        public string? RegisterEmailFormTitle { get; set; }
        public string? RegisterEmailFormContent { get; set; }
        public string? RegistrationEmailFormTitle { get; set; }
        public string? RegistrationEmailFormContent { get; set; }
        public string? ResetPasswordEmailFormTitle { get; set; }
        public string? ResetPasswordEmailFormContent { get; set; }
        public string? ChangedPasswordEmailFormTitle { get; set; }
        public string? ChangedPasswordEmailFormContent { get; set; }
        public string? WithdrawEmailFormTitle { get; set; }
        public string? WithdrawEmailFormContent { get; set; }
        public string? EmailVerifyFormTitle { get; set; }
        public string? EmailVerifyFormContent { get; set; }
        public string? ChangedEmailFormTitle { get; set; }
        public string? ChangedEmailFormContent { get; set; }
    }

    // ==================================================
    // 외부 API 설정 (External)
    // ==================================================
    public sealed class ExternalApiConfig
    {
        /** YouTube **/
        public string? YouTubeApiKeyEnc { get; set; }
        public string? YouTubeApiName { get; set; }

        /** 구글 **/
        public string? GoogleClientId { get; set; }
        public string? GoogleClientSecretEnc { get; set; }
        public string? GoogleAppId { get; set; }

        /** 다날 페이 **/
        /// <summary>Danal 결제 환경 (test / live)</summary>
        public string? DanalPayMode { get; set; }
        /// <summary>Danal Test CPID</summary>
        public string? DanalTestCpid { get; set; }
        /// <summary>Danal Test Client Key (암호화 저장 권장)</summary>
        public string? DanalTestClientKeyEnc { get; set; }
        /// <summary>Danal Test Secret Key (암호화 저장 권장)</summary>
        public string? DanalTestSecretKeyEnc { get; set; }
        /// <summary>Danal Live CPID</summary>
        public string? DanalLiveCpid { get; set; }
        /// <summary>Danal Live Client Key (암호화 저장 권장)</summary>
        public string? DanalLiveClientKeyEnc { get; set; }
        /// <summary>Danal Live Secret Key (암호화 저장 권장)</summary>
        public string? DanalLiveSecretKeyEnc { get; set; }
    }

    // ==================================================
    // 결제 설정 (Payment)
    // ==================================================
    public sealed class PaymentConfig
    {
        /** 다날 페이 수수료 **/
        /// <summary>다날 신용카드 수수료(%)</summary>
        public decimal? DanalCardFeeRate { get; set; }
        /// <summary>다날 신용카드 수수료(원)</summary>
        public decimal? DanalCardFeeAmount { get; set; }
        /// <summary>다날 계좌이체 수수료(%)</summary>
        public decimal? DanalTransferFeeRate { get; set; }
        /// <summary>다날 계좌이체 수수료(원)</summary>
        public decimal? DanalTransferFeeAmount { get; set; }
        /// <summary>다날 가상계좌 수수료(%)</summary>
        public decimal? DanalVbankFeeRate { get; set; }
        /// <summary>다날 가상계좌 수수료(원)</summary>
        public decimal? DanalVbankFeeAmount { get; set; }
        /// <summary>다날 간편결제 수수료(%)</summary>
        public decimal? DanalSimpleFeeRate { get; set; }
        /// <summary>다날 간편결제 수수료(원)</summary>
        public decimal? DanalSimpleFeeAmount { get; set; }
    }

    // ==================================================
    // 코인/시세 설정 (Crypto)
    // ==================================================
    public sealed class CryptoConfig
    {
        public int TickerRefreshSeconds { get; set; } = 5;
        public decimal SurgeThreshold { get; set; } = 5.0m;
        public decimal PlungeThreshold { get; set; } = -5.0m;
        public int MainPageCoinCount { get; set; } = 10;
    }

    #endregion
}