import { Platform } from '../enums/platform.enum'
import {
  VersionCode,
  VersionName,
  BuildNumber,
  DownloadUrl,
  FileSize,
  FileSha256,
  Changelog,
  MinOsVersion,
} from '../value-objects'
import * as crypto from 'crypto'

export class AppVersion {
  private _id: string
  private _platform: Platform
  private _versionCode: VersionCode
  private _versionName: VersionName
  private _buildNumber: BuildNumber
  private _downloadUrl: DownloadUrl
  private _fileSize: FileSize
  private _fileSha256: FileSha256
  private _changelog: Changelog
  private _isForceUpdate: boolean
  private _isEnabled: boolean
  private _minOsVersion: MinOsVersion | null
  private _releaseDate: Date | null
  private _createdAt: Date
  private _updatedAt: Date
  private _createdBy: string
  private _updatedBy: string | null

  private constructor() {}

  // Getters
  get id(): string {
    return this._id
  }

  get platform(): Platform {
    return this._platform
  }

  get versionCode(): VersionCode {
    return this._versionCode
  }

  get versionName(): VersionName {
    return this._versionName
  }

  get buildNumber(): BuildNumber {
    return this._buildNumber
  }

  get downloadUrl(): DownloadUrl {
    return this._downloadUrl
  }

  get fileSize(): FileSize {
    return this._fileSize
  }

  get fileSha256(): FileSha256 {
    return this._fileSha256
  }

  get changelog(): Changelog {
    return this._changelog
  }

  get isForceUpdate(): boolean {
    return this._isForceUpdate
  }

  get isEnabled(): boolean {
    return this._isEnabled
  }

  get minOsVersion(): MinOsVersion | null {
    return this._minOsVersion
  }

  get releaseDate(): Date | null {
    return this._releaseDate
  }

  get createdAt(): Date {
    return this._createdAt
  }

  get updatedAt(): Date {
    return this._updatedAt
  }

  get createdBy(): string {
    return this._createdBy
  }

  get updatedBy(): string | null {
    return this._updatedBy
  }

  // 工厂方法 - 创建新版本
  static create(params: {
    platform: Platform
    versionCode: VersionCode
    versionName: VersionName
    buildNumber: BuildNumber
    downloadUrl: DownloadUrl
    fileSize: FileSize
    fileSha256: FileSha256
    changelog: Changelog
    isForceUpdate: boolean
    minOsVersion?: MinOsVersion | null
    releaseDate?: Date | null
    createdBy: string
  }): AppVersion {
    const version = new AppVersion()
    version._id = crypto.randomUUID()
    version._platform = params.platform
    version._versionCode = params.versionCode
    version._versionName = params.versionName
    version._buildNumber = params.buildNumber
    version._downloadUrl = params.downloadUrl
    version._fileSize = params.fileSize
    version._fileSha256 = params.fileSha256
    version._changelog = params.changelog
    version._isForceUpdate = params.isForceUpdate
    version._isEnabled = true // 默认启用
    version._minOsVersion = params.minOsVersion ?? null
    version._releaseDate = params.releaseDate ?? null
    version._createdAt = new Date()
    version._updatedAt = new Date()
    version._createdBy = params.createdBy
    version._updatedBy = null
    return version
  }

  // 从持久化恢复
  static reconstitute(params: {
    id: string
    platform: Platform
    versionCode: VersionCode
    versionName: VersionName
    buildNumber: BuildNumber
    downloadUrl: DownloadUrl
    fileSize: FileSize
    fileSha256: FileSha256
    changelog: Changelog
    isForceUpdate: boolean
    isEnabled: boolean
    minOsVersion: MinOsVersion | null
    releaseDate: Date | null
    createdAt: Date
    updatedAt: Date
    createdBy: string
    updatedBy: string | null
  }): AppVersion {
    const version = new AppVersion()
    version._id = params.id
    version._platform = params.platform
    version._versionCode = params.versionCode
    version._versionName = params.versionName
    version._buildNumber = params.buildNumber
    version._downloadUrl = params.downloadUrl
    version._fileSize = params.fileSize
    version._fileSha256 = params.fileSha256
    version._changelog = params.changelog
    version._isForceUpdate = params.isForceUpdate
    version._isEnabled = params.isEnabled
    version._minOsVersion = params.minOsVersion
    version._releaseDate = params.releaseDate
    version._createdAt = params.createdAt
    version._updatedAt = params.updatedAt
    version._createdBy = params.createdBy
    version._updatedBy = params.updatedBy
    return version
  }

  // 业务方法
  isNewerThan(currentVersionCode: VersionCode): boolean {
    return this._versionCode.isNewerThan(currentVersionCode)
  }

  shouldForceUpdate(): boolean {
    return this._isForceUpdate && this._isEnabled
  }

  disable(updatedBy: string): void {
    this._isEnabled = false
    this._updatedBy = updatedBy
    this._updatedAt = new Date()
  }

  enable(updatedBy: string): void {
    this._isEnabled = true
    this._updatedBy = updatedBy
    this._updatedAt = new Date()
  }

  setForceUpdate(force: boolean, updatedBy: string): void {
    this._isForceUpdate = force
    this._updatedBy = updatedBy
    this._updatedAt = new Date()
  }

  setReleaseDate(date: Date | null, updatedBy: string): void {
    this._releaseDate = date
    this._updatedBy = updatedBy
    this._updatedAt = new Date()
  }

  update(params: {
    downloadUrl?: DownloadUrl
    fileSize?: FileSize
    fileSha256?: FileSha256
    changelog?: Changelog
    isForceUpdate?: boolean
    minOsVersion?: MinOsVersion | null
    releaseDate?: Date | null
    updatedBy: string
  }): void {
    if (params.downloadUrl) this._downloadUrl = params.downloadUrl
    if (params.fileSize) this._fileSize = params.fileSize
    if (params.fileSha256) this._fileSha256 = params.fileSha256
    if (params.changelog) this._changelog = params.changelog
    if (params.isForceUpdate !== undefined) this._isForceUpdate = params.isForceUpdate
    if (params.minOsVersion !== undefined) this._minOsVersion = params.minOsVersion
    if (params.releaseDate !== undefined) this._releaseDate = params.releaseDate
    this._updatedBy = params.updatedBy
    this._updatedAt = new Date()
  }
}
