import { PhotoHelper } from '@pura/picker_utils'
import { TitleBar } from '../../../../view/TitleBar'
import { photoAccessHelper } from '@kit.MediaLibraryKit'
import { BusinessError, systemDateTime } from '@kit.BasicServicesKit'
import { AppUtil, FileUtil, MD5 } from '@pura/harmony-utils'
import { ToastUtils } from '../../../../utils/ToastUtils'
import { fileIo, ReadOptions } from '@kit.CoreFileKit'
import { SaveUtils } from '../../../../utils/SaveUtils'
import { LoadingDialog } from '../../../../dialog/LoadingDialog'
import { DownloadDialog, DownloadStatus } from '../../../../dialog/DownloadDialog'
import { EventConstants } from '../../../../common/EventConstants'
import { TipDialog } from '../../../../dialog/TipDialog'
import { avSessionManager } from '../../../../manager/AVSessionManager'
import { AuthViewModel } from '../../../../viewModel/AuthViewModel'
import { VipAuthEntity as VipAuthEntity } from '../../../../entity/VipAuthEntity'
import { LoginManager } from '../../../../manager/LoginGlobalManager'
import { RouterUrls } from '../../../../common/RouterUrls'
import { router } from '@kit.ArkUI'
import { EventReportManager } from '../../../../manager/EventReportManager'
import { cryptoFramework } from '@kit.CryptoArchitectureKit'
import { buffer } from '@kit.ArkTS'

@Entry
@ComponentV2
struct MD5ResetPage {
  private viewModel: AuthViewModel = new AuthViewModel(this.getUIContext())
  private controller: VideoController = new VideoController()

  @Local oldMd5?: string
  @Local newMd5?: string
  @Local uri?: string
  @Local currentTime: number = 0
  @Local durationTime: number = 0
  @Local isPlaying: boolean = false
  @Local isSuccess: boolean = false

  @Monitor('viewModel.authInfo')
  onPermissionInfoChange(monitor: IMonitor) {
    const info = monitor.value()?.now as VipAuthEntity;
    if (info.auth) {
      if (!LoginManager.isLogin()) {
        this.getUIContext().getRouter().pushUrl({url: RouterUrls.LOGIN_PAGE, params: {from: 1}}, router.RouterMode.Single)
        return;
      }
      this.doSave()
    } else {
      if (!info.auth_ad) {
        this.getUIContext().getRouter().pushUrl({url: RouterUrls.VIP_PAGE, params: {origin: 'md5Reset'}})
        EventReportManager.eventReport(EventConstants.JUMP_TO_MEMBER_RECHARGE, 'md5Reset')
        return;
      }
    }
  }

  @Monitor('viewModel.errorCode')
  onErrorCodeChange(monitor: IMonitor) {
    const errorCode = monitor.value()?.now as number;
    if (errorCode === 12002 || errorCode === 12003 || errorCode === 12004) {
      this.getUIContext().getRouter().pushUrl({url: RouterUrls.RECHARGE_DIAMOND_PAGE});
      EventReportManager.eventReport(EventConstants.JUMP_TO_RECHARGE_DIAMOND, 'md5Reset')
      ToastUtils.show('M币已用完')
    }
  }

  doSave() {
    SaveUtils.saveImageVideoToAlbumDialog([this.uri!!])
      .then((saved) => {
        if (saved) {
          this.uri = undefined
          this.oldMd5 = undefined
          this.newMd5 = undefined
          this.isSuccess = false
          this.showDownloadDialog()
        } else {
          ToastUtils.show('保存失败')
        }
      })
      .catch((e: BusinessError) => {
        ToastUtils.show('保存失败：' + e.message)
      })
  }

  modifyMD5() {
    LoadingDialog.show(this.getUIContext())
    this.isSuccess = false
    let outputPath = FileUtil.getCacheDirPath() + FileUtil.separator + `scmf_${systemDateTime.getTime()}.mp4`
    if (FileUtil.accessSync(outputPath)) {
      FileUtil.unlinkSync(outputPath)
    }

    let file = FileUtil.openSync(this.uri!!, fileIo.OpenMode.READ_ONLY)
    // 复制文件到缓存目录下
    FileUtil.copyFileSync(file.fd, outputPath)
    FileUtil.closeSync(file)

    //在新文件追加空格
    let newFile = FileUtil.openSync(outputPath, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.APPEND)
    FileUtil.writeSync(newFile.fd, buffer.from(' ').buffer)
    FileUtil.closeSync(newFile)

    if (FileUtil.accessSync(outputPath)) {
      this.uri = FileUtil.getUriFromPath(outputPath)
      this.isSuccess = true
      this.isPlaying = false
      this.newMd5 = this.fileMD5(outputPath)
      ToastUtils.show('处理成功')
    } else {
      ToastUtils.show('处理失败')
    }
    LoadingDialog.dismiss()
  }

  selectVideo() {
    PhotoHelper.selectEasy({
      MIMEType: photoAccessHelper.PhotoViewMIMETypes.VIDEO_TYPE,
      maxSelectNumber: 1,
      isPhotoTakingSupported: false,
      isEditSupported: false,
      isOriginalSupported: false
    })
      .then((uris) => {
        if (uris.length != 0) {
          this.isSuccess = false
          this.controller.reset()
          this.uri = uris[0]
          this.oldMd5 = this.fileMD5(this.uri)
          this.newMd5 = undefined
        }
      })
  }

  /**
   * 获取文件的MD5值
   */
  fileMD5(uri: string): string {
  // 定义摘要类型
  let md = cryptoFramework.createMd('MD5');
  // 打开文件
  let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
  let fileBufferSize = 4096;
  let readSize = 0;
  let fileBuffer = new ArrayBuffer(fileBufferSize);
  let readOptions: ReadOptions = {
    offset: readSize,
    length: fileBufferSize
  };
  let readLength = fileIo.readSync(file.fd, fileBuffer, readOptions);
  while (readLength > 0) {
    // 更新摘要数据
    md.updateSync({ data: new Uint8Array(fileBuffer.slice(0, readLength)) });
    readSize += readLength;
    readOptions.offset = readSize;
    readLength = fileIo.readSync(file.fd, fileBuffer, readOptions);
  }
  // 计算摘要
  let mdResult = md.digestSync();
  return buffer.from(mdResult.data).toString('hex');
}

  showDownloadDialog() {
    DownloadDialog.show(this.getUIContext(), { status: DownloadStatus.COMPLETED, totalSize: 0, progress: 0, totalCount: 1, index: 0, callback: {
      confirm: () => {
        AppUtil.getContext().eventHub.emit(EventConstants.JumpToRecordEvent, 0)
        this.getUIContext().getRouter().back()
      }
    } })
  }

  formatTime(time: number): string {
    let minute: number = 0
    let second: number = 0
    if (time > 60) {
      minute = Math.trunc(time / 60)
      second = time % 60
      if (minute < 10) {
        if (second < 10) {
          return `0${minute}:0${second}`
        } else {
          return `0${minute}:${second}`
        }
      } else {
        if (second < 10) {
          return `${minute}:0${second}`
        } else {
          return `${minute}:${second}`
        }
      }
    } else {
      second = time
      if (second < 10) {
        return `00:0${second}`
      } else {
        return `00:${second}`
      }
    }
  }

  onBackPress(): boolean | void {
    if (this.isSuccess) {
      TipDialog.show(this.getUIContext(), {title:'温馨提示', content:'视频尚未保存，是否确定退出？', callback: {
        confirm: () => {
          this.getUIContext().getRouter().back()
        }
      }})
      return true
    }
    return false
  }

  build() {
    Column() {
      TitleBar({ title: 'MD5去重' })

      Stack() {
        Stack() {
          Stack() {
            Column() {
              Image($r('app.media.ic_add_video')).width(40).height(40)
              Text('请上传视频').fontColor($r('app.color.color_466afd')).fontSize(15).fontWeight(FontWeight.Medium).margin({ top: 8})
            }
          }
          .width('100%')
          .height('100%')
          .onClick(() => {
            this.selectVideo()
          })
          .visibility(this.uri ? Visibility.None : Visibility.Visible)

          RelativeContainer() {
            Video({
              src: this.uri, // 设置视频源
              controller: this.controller, //设置视频控制器，可以控制视频的播放状态
              posterOptions: { showFirstFrame: true }
            })
              .width('100%')
              .height('100%')
              .borderRadius(20)
              .backgroundColor(Color.White)
              .controls(false) // 设置是否显示默认控制条
              .autoPlay(false) // 设置是否自动播放
              .loop(false) // 设置是否循环播放
              .objectFit(ImageFit.Contain) // 设置视频填充模式
              .onPrepared((event) => {
                if (event) {
                  this.durationTime = event.duration
                }
              })
              .onUpdate((event) => {
                if (event) {
                  this.currentTime = event.time
                }
              })
              .onStart(() => {
                this.isPlaying = true
              })
              .onPause(() => {
                this.isPlaying = false
                avSessionManager.deactivate()
              })
              .onStop(() => {
                this.isPlaying = false
                avSessionManager.deactivate()
              })
              .onFinish(() => {
                this.isPlaying = false
                avSessionManager.deactivate()
              })
              .onError(() => {
                this.isPlaying = false
                avSessionManager.deactivate()
              })
              .onDisAppear(() => {
                avSessionManager.deactivate()
              })

            Image($r('app.media.ic_play_video'))
              .width(50)
              .height(50)
              .visibility(this.isPlaying ? Visibility.None : Visibility.Visible)
              .onClick(async () => {
                await avSessionManager.activate()
                this.controller.start()
              })
              .alignRules({
                left: { anchor: '__container__', align: HorizontalAlign.Start },
                top: { anchor: '__container__', align: VerticalAlign.Top },
                right: { anchor: '__container__', align: HorizontalAlign.End },
                bottom: { anchor: '__container__', align: VerticalAlign.Bottom },
              })

            Row() {
              Image(this.isPlaying ? $r('app.media.ic_player_controls_pause') : $r('app.media.ic_player_controls_play'))
                .width(20)
                .height(20)
                .margin({ right: 20 })
                .onClick(async () => {
                  if (this.isPlaying) {
                    this.controller.pause()
                  } else {
                    await avSessionManager.activate()
                    this.controller.start()
                  }
                })
              Text(this.formatTime(this.currentTime)).width(35).fontColor(Color.White).fontSize(12)
              Slider({
                value: this.currentTime,
                min: 0,
                max: this.durationTime
              })
                .blockColor(Color.White)
                .trackColor($r('app.color.color_60ffffff'))
                .onChange((value: number, mode: SliderChangeMode) => {
                  this.controller.setCurrentTime(value); // 设置视频播放的进度跳转到value处
                })
                .layoutWeight(1)
              Text(this.formatTime(this.durationTime)).width(35).fontColor(Color.White).fontSize(12)
            }
            .opacity(0.8)
            .width("100%")
            .borderRadius({bottomLeft: 20, bottomRight: 20})
            .backgroundColor('#1A000000')
            .padding({ left: 30, right: 30 })
            .alignRules({
              bottom: { anchor: '__container__', align: VerticalAlign.Bottom }
            })
          }
          .width('100%')
          .height('100%')
          .visibility(this.uri ? Visibility.Visible : Visibility.None)
        }
        .width('100%')
        .aspectRatio(1)
        .borderRadius(20)
        .backgroundColor(Color.White)
        .shadow({radius: 10, color: '#1a9399a1'})
      }
      .width('100%')
      .height('auto')
      .padding({left: 32, right: 32})
      .margin({top: 40})

      Text('旧-MD5：' + this.oldMd5)
        .textAlign(TextAlign.Center)
        .fontColor($r('app.color.color_212226'))
        .fontSize(15)
        .margin({top: 30})
        .visibility(this.oldMd5 ? Visibility.Visible : Visibility.None)

      Text('新-MD5：' + this.newMd5)
        .textAlign(TextAlign.Center)
        .fontColor($r('app.color.color_212226'))
        .fontSize(15)
        .margin({top: 15})
        .visibility(this.newMd5 ? Visibility.Visible : Visibility.None)

      Blank().layoutWeight(1)

      Stack() {
        Button('确认处理', { type: ButtonType.Capsule, stateEffect: true })
          .width('100%')
          .height(46)
          .fontColor(Color.White)
          .fontSize(15)
          .fontWeight(FontWeight.Medium)
          .backgroundColor($r('app.color.color_466afd'))
          .onClick(() => {
            this.controller.stop()
            if (this.uri) {
              this.modifyMD5()
            } else {
              ToastUtils.show('请上传视频')
            }
          })
          .visibility(!this.isSuccess ? Visibility.Visible : Visibility.None)

        Row() {
          Button({ type: ButtonType.Capsule, stateEffect: true }) {
            Row() {
              Image($r('app.media.ic_reupload')).width(20).height(20)
              Text('重新上传').fontColor($r('app.color.color_466afd')).fontSize(15).fontWeight(FontWeight.Medium)
            }
          }
          .height(46)
          .layoutWeight(1)
          .borderWidth(1)
          .borderColor($r('app.color.color_466afd'))
          .backgroundColor(Color.Transparent)
          .onClick(() => {
            this.controller.stop()
            this.selectVideo()
          })

          Blank().width(9)

          Button({ type: ButtonType.Capsule, stateEffect: true }) {
            Row() {
              Image($r('app.media.ic_download3')).width(20).height(20)
              Text('保存').fontColor(Color.White).fontSize(15).fontWeight(FontWeight.Medium)
            }
          }
          .height(46)
          .layoutWeight(1)
          .backgroundColor($r('app.color.color_466afd'))
          .onClick(() => {
            this.controller.stop()
            this.viewModel.checkVip()
          })
        }
        .visibility(this.isSuccess ? Visibility.Visible : Visibility.None)
      }
      .padding({left: 16, top: 9, right: 16, bottom: 30 })
      .backgroundColor(Color.White)
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.window_background'))
  }
}