namespace Synor.Sdk.Hosting;

public record HostingConfig
{
    public required string ApiKey { get; init; }
    public string Endpoint { get; init; } = "https://hosting.synor.io/v1";
    public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(60);
    public int Retries { get; init; } = 3;
    public bool Debug { get; init; } = false;
}

public enum DomainStatus { Pending, Active, Expired, Suspended }
public enum DeploymentStatus { Pending, Building, Deploying, Active, Failed, Inactive }
public enum CertificateStatus { Pending, Issued, Expired, Revoked }
public enum DnsRecordType { A, AAAA, CNAME, TXT, MX, NS, SRV, CAA }

public record DomainRecord
{
    public string? Cid { get; init; }
    public List<string>? Ipv4 { get; init; }
    public List<string>? Ipv6 { get; init; }
    public string? Cname { get; init; }
    public List<string>? Txt { get; init; }
    public Dictionary<string, string>? Metadata { get; init; }
}

public record Domain
{
    public required string Name { get; init; }
    public DomainStatus Status { get; init; }
    public required string Owner { get; init; }
    public long RegisteredAt { get; init; }
    public long ExpiresAt { get; init; }
    public bool AutoRenew { get; init; }
    public DomainRecord? Records { get; init; }
}

public record DomainAvailability
{
    public required string Name { get; init; }
    public bool Available { get; init; }
    public double? Price { get; init; }
    public bool Premium { get; init; }
}

public record RegisterDomainOptions
{
    public int? Years { get; init; }
    public bool? AutoRenew { get; init; }
}

public record DnsRecord
{
    public DnsRecordType Type { get; init; }
    public required string Name { get; init; }
    public required string Value { get; init; }
    public int Ttl { get; init; } = 3600;
    public int? Priority { get; init; }
}

public record DnsZone
{
    public required string Domain { get; init; }
    public required List<DnsRecord> Records { get; init; }
    public long UpdatedAt { get; init; }
}

public record Deployment
{
    public required string Id { get; init; }
    public required string Domain { get; init; }
    public required string Cid { get; init; }
    public DeploymentStatus Status { get; init; }
    public required string Url { get; init; }
    public long CreatedAt { get; init; }
    public long UpdatedAt { get; init; }
    public string? BuildLogs { get; init; }
    public string? ErrorMessage { get; init; }
}

public record DeployOptions
{
    public string? Domain { get; init; }
    public string? Subdomain { get; init; }
    public bool? Spa { get; init; }
    public bool? CleanUrls { get; init; }
    public bool? TrailingSlash { get; init; }
}

public record Certificate
{
    public required string Domain { get; init; }
    public CertificateStatus Status { get; init; }
    public bool AutoRenew { get; init; }
    public required string Issuer { get; init; }
    public long? IssuedAt { get; init; }
    public long? ExpiresAt { get; init; }
    public string? Fingerprint { get; init; }
}

public record ProvisionSslOptions
{
    public bool? IncludeWww { get; init; }
    public bool? AutoRenew { get; init; }
}

public record SiteConfig
{
    public required string Domain { get; init; }
    public string? Cid { get; init; }
    public Dictionary<string, string>? Headers { get; init; }
    public bool Spa { get; init; }
    public bool CleanUrls { get; init; } = true;
    public bool TrailingSlash { get; init; }
}

public record PageView { public required string Path { get; init; } public long Views { get; init; } }
public record Referrer { public required string ReferrerUrl { get; init; } public long Count { get; init; } }
public record Country { public required string CountryCode { get; init; } public long Count { get; init; } }

public record AnalyticsData
{
    public required string Domain { get; init; }
    public required string Period { get; init; }
    public long PageViews { get; init; }
    public long UniqueVisitors { get; init; }
    public long Bandwidth { get; init; }
    public required List<PageView> TopPages { get; init; }
}

public record AnalyticsOptions
{
    public string? Period { get; init; }
    public string? Start { get; init; }
    public string? End { get; init; }
}

internal record DomainsResponse { public List<Domain>? Domains { get; init; } }
internal record DeploymentsResponse { public List<Deployment>? Deployments { get; init; } }
internal record PurgeResponse { public long Purged { get; init; } }
internal record HostingHealthResponse { public required string Status { get; init; } }

public class HostingException : Exception
{
    public string? Code { get; }
    public int StatusCode { get; }
    public HostingException(string message, string? code = null, int statusCode = 0) : base(message)
    {
        Code = code;
        StatusCode = statusCode;
    }
}
