/**
 * Type definitions for Onebox
 */

import type * as servezoneInterfaces from '@serve.zone/interfaces';

// Service types
export interface IService {
  id?: number;
  name: string;
  image: string;
  registry?: string;
  envVars: Record<string, string>;
  volumes?: IServiceVolume[];
  publishedPorts?: IServicePublishedPort[];
  port: number;
  domain?: string;
  containerID?: string;
  status: 'stopped' | 'starting' | 'running' | 'stopping' | 'failed';
  createdAt: number;
  updatedAt: number;
  // Onebox Registry fields
  useOneboxRegistry?: boolean;
  registryRepository?: string;
  registryImageTag?: string;
  autoUpdateOnPush?: boolean;
  imageDigest?: string;
  // Platform service requirements
  platformRequirements?: IPlatformRequirements;
  // Backup settings
  includeImageInBackup?: boolean;
  // App Store template tracking
  appTemplateId?: string;
  appTemplateVersion?: string;
}

export type IHostedAppLifecycleState = servezoneInterfaces.data.IHostedAppLifecycleState;

export interface IHostedAppLifecycleRecord {
  id?: number;
  serviceId: number;
  appInstanceId: string;
  controlToken: string;
  hostType: 'onebox';
  state: IHostedAppLifecycleState;
  createdAt: number;
  updatedAt: number;
}

export interface IServiceVolume {
  name?: string;
  source?: string;
  mountPath: string;
  driver?: string;
  readOnly?: boolean;
  backup?: boolean;
  options?: Record<string, string>;
}

export type TServicePortProtocol = 'tcp' | 'udp';

export interface IServicePublishedPort {
  targetPort: number;
  targetPortEnd?: number;
  publishedPort?: number;
  publishedPortEnd?: number;
  protocol?: TServicePortProtocol;
  hostIp?: string;
}

// Registry types
export interface IRegistry {
  id?: number;
  url: string;
  username: string;
  passwordEncrypted: string;
  createdAt: number;
}

// Registry token types
export interface IRegistryToken {
  id?: number;
  name: string;
  tokenHash: string;
  type: 'global' | 'ci';
  scope: 'all' | string[];  // 'all' or array of service names
  expiresAt: number | null;
  createdAt: number;
  lastUsedAt: number | null;
  createdBy: string;
}

export interface ICreateRegistryTokenRequest {
  name: string;
  type: 'global' | 'ci';
  scope: 'all' | string[];
  expiresIn: '30d' | '90d' | '365d' | 'never';
}

export interface IRegistryTokenView {
  id: number;
  name: string;
  type: 'global' | 'ci';
  scope: 'all' | string[];
  scopeDisplay: string;
  expiresAt: number | null;
  createdAt: number;
  lastUsedAt: number | null;
  createdBy: string;
  isExpired: boolean;
}

export interface ITokenCreatedResponse {
  token: IRegistryTokenView;
  plainToken: string;  // Only shown once at creation
}

// Platform service types
export type TPlatformServiceType = 'mongodb' | 'minio' | 'redis' | 'postgresql' | 'rabbitmq' | 'smartproxy' | 'clickhouse' | 'mariadb';
export type TPlatformResourceType = 'database' | 'bucket' | 'cache' | 'queue';
export type TPlatformServiceStatus = 'stopped' | 'starting' | 'running' | 'stopping' | 'failed';

export interface IPlatformService {
  id?: number;
  name: string;
  type: TPlatformServiceType;
  status: TPlatformServiceStatus;
  containerId?: string;
  config: IPlatformServiceConfig;
  adminCredentialsEncrypted?: string;
  createdAt: number;
  updatedAt: number;
}

export interface IPlatformServiceConfig {
  image: string;
  port: number;
  volumes?: string[];
  command?: string;
  environment?: Record<string, string>;
}

export interface IPlatformResource {
  id?: number;
  platformServiceId: number;
  serviceId: number;
  resourceType: TPlatformResourceType;
  resourceName: string;
  credentialsEncrypted: string;
  createdAt: number;
}

export interface IPlatformRequirements {
  mongodb?: boolean;
  s3?: boolean;
  clickhouse?: boolean;
  redis?: boolean;
  mariadb?: boolean;
}

export interface IProvisionedResource {
  type: TPlatformResourceType;
  name: string;
  credentials: Record<string, string>;
  envVars: Record<string, string>;
}

export interface IEnvVarMapping {
  envVar: string;
  credentialPath: string;
}

// Nginx configuration types
export interface INginxConfig {
  id?: number;
  serviceId: number;
  domain: string;
  port: number;
  sslEnabled: boolean;
  configTemplate: string;
  createdAt: number;
  updatedAt: number;
}

// Domain management types
export interface IDomain {
  id?: number;
  domain: string;
  dnsProvider: 'cloudflare' | 'manual' | 'dcrouter' | null;
  cloudflareZoneId?: string;
  isObsolete: boolean;
  defaultWildcard: boolean;
  createdAt: number;
  updatedAt: number;
}

export interface ICertificate {
  id?: number;
  domainId: number;
  certDomain: string;
  isWildcard: boolean;
  certPem: string;       // Certificate PEM content
  keyPem: string;        // Private key PEM content
  fullchainPem: string;  // Full chain PEM content (cert + intermediates)
  expiryDate: number;
  issuer: string;
  isValid: boolean;
  createdAt: number;
  updatedAt: number;
}

export interface ICertRequirement {
  id?: number;
  serviceId: number;
  domainId: number;
  subdomain: string;
  certificateId?: number;
  status: 'pending' | 'active' | 'renewing';
  createdAt: number;
  updatedAt: number;
}

export interface IDomainView {
  domain: IDomain;
  certificates: ICertificate[];
  requirements: ICertRequirement[];
  serviceCount: number;
  certificateStatus: 'valid' | 'expiring-soon' | 'expired' | 'pending' | 'none';
  daysRemaining: number | null;
}

// SSL certificate type - stores certificate content directly in database
export interface ISslCertificate {
  id?: number;
  domain: string;
  certPem: string;       // Certificate PEM content
  keyPem: string;        // Private key PEM content
  fullchainPem: string;  // Full chain PEM content (cert + intermediates)
  expiryDate: number;
  issuer: string;
  createdAt: number;
  updatedAt: number;
}

// DNS record types
export interface IDnsRecord {
  id?: number;
  domain: string;
  type: 'A' | 'AAAA' | 'CNAME';
  value: string;
  cloudflareID?: string;
  createdAt: number;
  updatedAt: number;
}

// Metrics types
export interface IMetric {
  id?: number;
  serviceId: number;
  timestamp: number;
  cpuPercent: number;
  memoryUsed: number;
  memoryLimit: number;
  networkRxBytes: number;
  networkTxBytes: number;
}

// Log entry types
export interface ILogEntry {
  id?: number;
  serviceId: number;
  timestamp: number;
  message: string;
  level: 'info' | 'warn' | 'error' | 'debug';
  source: 'stdout' | 'stderr';
}

// User types
export interface IUser {
  id?: number;
  username: string;
  passwordHash: string;
  role: 'admin' | 'user';
  createdAt: number;
  updatedAt: number;
}

// Settings types
export interface ISetting {
  key: string;
  value: string;
  updatedAt: number;
}

// Application settings
export interface IAppSettings {
  serverIP?: string;
  adminUiDomain?: string;
  cloudflareToken?: string;
  cloudflareZoneId?: string;
  dcrouterMode?: 'managed' | 'external' | 'disabled';
  dcrouterManagedImage?: string;
  dcrouterManagedOpsPort?: number;
  dcrouterManagedHttpPort?: number;
  dcrouterManagedHttpsPort?: number;
  dcrouterManagedDataDir?: string;
  dcrouterGatewayUrl?: string;
  dcrouterGatewayApiToken?: string;
  dcrouterGatewayClientId?: string;
  /** @deprecated Use dcrouterGatewayClientId. */
  dcrouterWorkHosterId?: string;
  dcrouterTargetHost?: string;
  dcrouterTargetPort?: number;
  acmeEmail?: string;
  dataDir?: string;
  httpPort?: number;
  httpsPort?: number;
  metricsInterval?: number;
  autoRenewCerts?: boolean;
  renewalThreshold?: number;
  forceHttps?: boolean;
  logRetentionDays?: number;
}

// Container stats from Docker
export interface IContainerStats {
  cpuPercent: number;
  memoryUsed: number;
  memoryLimit: number;
  memoryPercent: number;
  networkRx: number;
  networkTx: number;
}

// Service deployment options
export interface IServiceDeployOptions {
  name: string;
  image: string;
  registry?: string;
  envVars?: Record<string, string>;
  volumes?: IServiceVolume[];
  publishedPorts?: IServicePublishedPort[];
  port: number;
  domain?: string;
  autoSSL?: boolean;
  autoDNS?: boolean;
  // Onebox Registry options
  useOneboxRegistry?: boolean;
  registryImageTag?: string;
  autoUpdateOnPush?: boolean;
  imageDigest?: string;
  // Platform service requirements
  enableMongoDB?: boolean;
  enableS3?: boolean;
  enableClickHouse?: boolean;
  enableRedis?: boolean;
  enableMariaDB?: boolean;
  // App Store template tracking
  appTemplateId?: string;
  appTemplateVersion?: string;
}

// HTTP API request/response types
export interface IApiResponse<T = unknown> {
  success: boolean;
  data?: T;
  error?: string;
  message?: string;
}

export interface ILoginRequest {
  username: string;
  password: string;
}

export interface ILoginResponse {
  token: string;
  user: {
    username: string;
    role: string;
  };
}

// CLI command types
export interface ICliArgs {
  _: string[];
  [key: string]: unknown;
}

// Backup types
export type TBackupRestoreMode = 'restore' | 'import' | 'clone';

// Retention policy for GFS (Grandfather-Father-Son) time-window based retention
export interface IRetentionPolicy {
  hourly: number;   // 0 = disabled, else keep up to N backups from last 24h
  daily: number;    // Keep 1 backup per day for last N days
  weekly: number;   // Keep 1 backup per week for last N weeks
  monthly: number;  // Keep 1 backup per month for last N months
}

// Default retention presets
export const RETENTION_PRESETS = {
  standard: { hourly: 0, daily: 7, weekly: 4, monthly: 12 },
  frequent: { hourly: 24, daily: 7, weekly: 4, monthly: 12 },
  minimal: { hourly: 0, daily: 3, weekly: 2, monthly: 6 },
  longterm: { hourly: 0, daily: 14, weekly: 8, monthly: 24 },
} as const;

export type TRetentionPreset = keyof typeof RETENTION_PRESETS | 'custom';

export interface IBackup {
  id?: number;
  serviceId: number;
  serviceName: string;  // Denormalized for display
  filename: string;
  snapshotId?: string;  // ContainerArchive snapshot ID (new backups)
  sizeBytes: number;
  storedSizeBytes?: number;  // Actual stored size after dedup+compression
  createdAt: number;
  includesImage: boolean;
  platformResources: TPlatformServiceType[];  // Which platform types were backed up
  checksum: string;
  // Scheduled backup fields
  scheduleId?: number;  // Links backup to its schedule for retention
}

export interface IBackupManifest {
  version: string;
  createdAt: number;
  oneboxVersion: string;
  serviceName: string;
  includesImage: boolean;
  platformResources: TPlatformServiceType[];
  checksum: string;
}

export interface IBackupServiceConfig {
  name: string;
  image: string;
  registry?: string;
  envVars: Record<string, string>;
  volumes?: IServiceVolume[];
  publishedPorts?: IServicePublishedPort[];
  port: number;
  domain?: string;
  useOneboxRegistry?: boolean;
  registryRepository?: string;
  registryImageTag?: string;
  autoUpdateOnPush?: boolean;
  platformRequirements?: IPlatformRequirements;
  includeImageInBackup?: boolean;
}

export interface IBackupPlatformResource {
  resourceType: TPlatformResourceType;
  resourceName: string;
  platformServiceType: TPlatformServiceType;
  credentials: Record<string, string>;  // Decrypted for backup, re-encrypted on restore
}

export interface IBackupResult {
  backup: IBackup;
  filePath?: string;  // Legacy file-based backups only
  snapshotId?: string;  // ContainerArchive snapshot ID
}

export interface IRestoreOptions {
  mode: TBackupRestoreMode;
  newServiceName?: string;  // Required for 'import' and 'clone' modes
  skipPlatformData?: boolean;  // Restore config only, skip DB/bucket data
  overwriteExisting?: boolean; // For 'restore' mode
}

export interface IRestoreResult {
  service: IService;
  platformResourcesRestored: number;
  warnings: string[];
}

// Backup scheduling types (GFS retention scheme)
export type TBackupScheduleScope = 'all' | 'pattern' | 'service';

export interface IBackupSchedule {
  id?: number;
  scopeType: TBackupScheduleScope;
  scopePattern?: string;        // Glob pattern for 'pattern' scope type
  serviceId?: number;           // Only for 'service' scope type
  serviceName?: string;         // Only for 'service' scope type
  cronExpression: string;
  retention: IRetentionPolicy;  // Per-tier retention counts
  enabled: boolean;
  lastRunAt: number | null;
  nextRunAt: number | null;
  lastStatus: 'success' | 'failed' | null;
  lastError: string | null;
  createdAt: number;
  updatedAt: number;
}

export interface IBackupScheduleCreate {
  scopeType: TBackupScheduleScope;
  scopePattern?: string;        // Required for 'pattern' scope type
  serviceName?: string;         // Required for 'service' scope type
  cronExpression: string;
  retention: IRetentionPolicy;
  enabled?: boolean;
}

export interface IBackupScheduleUpdate {
  cronExpression?: string;
  retention?: IRetentionPolicy;
  enabled?: boolean;
}

// Backup creation options (for scheduled backups)
export interface IBackupCreateOptions {
  scheduleId?: number;
}
