import { media } from "@kit.MediaKit";
import { fileIo } from "@kit.CoreFileKit";
import { avSessionManager } from "../manager/AVSessionManager";
import { MediaRecordEntity } from "../entity/MediaRecordEntity";
import { MediaAction, MediaManager, MediaType } from "../manager/MediaManager";
import { ShareManager } from "../manager/ShareManager";
import { TipDialog } from "./TipDialog";
import { ToastUtils } from "../utils/ToastUtils";
import { LocalMediaManager } from "../manager/LocalMediaManager";
import { AppUtil } from "@pura/harmony-utils";
import { EventConstants } from "../common/EventConstants";

@CustomDialog
export struct AudioPlayerDialog {
  controller: CustomDialogController;

  @State index: number = 0

  @State media?: MediaRecordEntity = undefined
  @State currentTime: number = 0
  @State durationTime: number = 0
  @State isPlaying: boolean = false
  @State mediaList: Array<MediaRecordEntity> = [];

  private avPlayer?: media.AVPlayer;

  aboutToAppear(): void {
    this.initPlayer()
    this.initParams()
  }

  aboutToDisappear(): void {
    if (this.avPlayer) {
      this.avPlayer.release()
    }
  }

  async initPlayer() {
    this.avPlayer = await media.createAVPlayer()
    // 创建状态机变化回调函数
    this.setAVPlayerCallback()
  }

  async initParams() {
    this.mediaList = await MediaManager.getAudioList()
    if (this.mediaList.length > this.index) {
      this.media = this.mediaList[this.index]
      if (this.media.uri) {
        // 打开相应的资源文件地址获取fd
        let file = await fileIo.open(this.media.uri)
        this.avPlayer!!.url = 'fd://' + file.fd
      }
    }
  }

  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}`
      }
    }
  }

  // 注册avplayer回调函数
  setAVPlayerCallback() {
    this.avPlayer!!.on('error', (err) => {
      console.error(`播放器发生错误，错误码：${err.code}, 错误信息：${err.message}`);
      // 调用reset重置资源，触发idle状态
      this.isPlaying = false
      this.avPlayer!!.reset();
      avSessionManager.deactivate()
    })
    // 状态机变化回调函数
    this.avPlayer!!.on('stateChange', async (state, reason) => {
      switch (state) {
        case 'initialized':
          console.info('资源初始化完成');
          // 资源初始化完成，开始准备文件
          this.avPlayer!!.prepare();
          break;
        case 'prepared':
          console.info('资源准备完成');
          // 资源准备完成，开始准备文件
          this.durationTime = Math.trunc(this.avPlayer!!.duration / 1000)
          this.currentTime = this.avPlayer!!.currentTime;

          await avSessionManager.activate()
          this.avPlayer!!.play();
          break;
        case 'completed':
          console.info('播放完成');
          this.isPlaying = false
          this.avPlayer!!.off('bufferingUpdate')
          AppStorage.setOrCreate('currentTime', this.durationTime);
          avSessionManager.deactivate()
          break;
        case 'playing':
          console.info('播放开始');
          this.isPlaying = true
          break;
        case 'released':
        case 'stopped':
        case 'error':
        case 'paused':
          console.info('播放暂停');
          this.isPlaying = false
          avSessionManager.deactivate()
          break;
      }
    })
    // 时间上报监听函数
    this.avPlayer!!.on('timeUpdate', (time: number) => {
      this.currentTime = Math.trunc(time / 1000);
    });
  }

  build() {
    RelativeContainer() {
      Image($r('app.media.ic_close_dialog')).width(20).height(20)
        .alignRules({
          right: {anchor: '__container__', align: HorizontalAlign.End}
        })
        .margin({top: 12, right: 12})
        .onClick(() => {
          this.controller.close()
        })
        .id('iv_close')

      Text(this.media?.name).fontColor($r('app.color.color_212226')).fontSize(16)
        .alignRules({
          top: {anchor: 'iv_close', align: VerticalAlign.Bottom}
        })
        .margin({left: 16, top: 6})
        .id('tv_name')

      Row() {
        Text(this.formatTime(this.currentTime)).width(35).fontColor($r('app.color.color_212226')).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.avPlayer!!.seek(value * 1000, 2); // 设置视频播放的进度跳转到value处
            this.currentTime = value;
          })
          .layoutWeight(1)
        Text(this.formatTime(this.durationTime)).width(35).fontColor($r('app.color.color_212226')).fontSize(12)
      }
      .alignRules({
        top: {anchor: 'tv_name', align: VerticalAlign.Bottom}
      })
      .width('100%')
      .padding({left:16, right: 16})
      .margin({top: 20})
      .id('row_progress')

      Row() {
        Image(this.index > 0 ? $r('app.media.ic_last_audio_enable') : $r('app.media.ic_last_audio_disable')).width(20).height(20)
          .onClick(async () => {
            if (this.index > 0) {
              await this.avPlayer!!.pause()
              await this.avPlayer!!.reset()
              this.index--
              this.media = this.mediaList[this.index]
              if (this.media.uri) {
                // 打开相应的资源文件地址获取fd
                let file = await fileIo.open(this.media.uri)
                this.avPlayer!!.url = 'fd://' + file.fd
              }
            }
          })

        Image(this.isPlaying ? $r('app.media.ic_audio_pause') : $r('app.media.ic_audio_play')).width(30).height(30)
          .margin({left: 50, right: 50})
          .onClick(async () => {
            if (this.isPlaying) {
              this.avPlayer!!.pause()
            } else {
              await avSessionManager.activate()
              this.avPlayer!!.play()
            }
          })

        Image(this.index < this.mediaList.length - 1 ? $r('app.media.ic_last_audio_enable') : $r('app.media.ic_last_audio_disable')).width(20).height(20)
          .rotate({angle: 180})
          .onClick(async () => {
            if (this.index < this.mediaList.length - 1) {
              await this.avPlayer!!.pause()
              await this.avPlayer!!.reset()
              this.index++
              this.media = this.mediaList[this.index]
              if (this.media.uri) {
                // 打开相应的资源文件地址获取fd
                let file = await fileIo.open(this.media.uri)
                this.avPlayer!!.url = 'fd://' + file.fd
              }
            }
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.Center)
      .alignRules({
        top: {anchor: 'row_progress', align: VerticalAlign.Bottom}
      })
      .margin({top: 26})
      .id('row_controller')

      Row() {
        Button({ type: ButtonType.Capsule, stateEffect: true }) {
          Row() {
            Image($r('app.media.ic_share_audio')).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(() => {
          if (this.media?.uri) {
            this.avPlayer!!.pause()
            ShareManager.shareFile(this.media.uri)
          }
        })

        Blank().width(9)

        Button({ type: ButtonType.Capsule, stateEffect: true }) {
          Row() {
            Image($r('app.media.ic_delete_material')).width(20).height(20)
            Text('删除').fontColor(Color.White).fontSize(15).fontWeight(FontWeight.Medium)
          }
        }
        .height(46)
        .layoutWeight(1)
        .backgroundColor($r('app.color.color_466afd'))
        .onClick(() => {
          if (this.media) {
            this.avPlayer!!.pause()
            TipDialog.show(this.getUIContext(), {
              title: '提示', content: '确定删除该音频？', callback: {
                confirm: () => {
                  fileIo.unlink(this.media!!.uri)
                    .then(() => {
                      this.controller.close()
                      ToastUtils.show('删除成功')
                      LocalMediaManager.delete(this.media!!.name!!)
                      AppUtil.getContext().eventHub.emit(EventConstants.MediaActionEvent, MediaType.AUDIO, MediaAction.DELETE)
                    })
                    .catch(() => {
                      ToastUtils.show('删除失败, 请到文件管理中手动删除')
                    })
                }
              }
            })
          }
        })
      }
      .alignRules({
        top: {anchor: 'row_controller', align: VerticalAlign.Bottom}
      })
      .padding({left: 16, top: 9, right: 16, bottom: 30})
      .margin({top: 38})
      .backgroundColor(Color.White)
    }
    .width('100%')
    .height('auto')
    .backgroundColor($r('app.color.window_background'))
  }
}