import { AppUtil, FileUtil, KeyboardUtil, ObjectUtil, PasteboardUtil, StrUtil } from '@pura/harmony-utils';
import { RouterUrls } from '../../../../common/RouterUrls';
import { MaterialLoadingDialog } from '../../../../dialog/MaterialLoadingDialog';
import {
  AudioMaterial,
  ImageMaterial,
  MaterialDetailEntity,
  MaterialInfoEntity,
  MediaEntity,
  TextMaterial,
  VideoMaterial
} from '../../../../entity/MaterialInfoEntity';
import { VipPermissionEntity } from '../../../../entity/VipPermissionEntity';
import { LoginManager } from '../../../../manager/LoginGlobalManager';
import { ToastUtils } from '../../../../utils/ToastUtils';
import { TakeMaterialViewModel } from '../../../../viewModel/TakeMaterialViewModel';
import { AudioMaterialPage } from './material/AudioMaterialPage';
import { ImageMaterialPage } from './material/ImageMaterialPage';
import { TextMaterialPage } from './material/TextMaterialPage';
import { VideoMaterialPage } from './material/VideoMaterialPage';
import { router } from '@kit.ArkUI';
import { MediaDownloader } from '../../../../net/MediaDownloader';
import { ShareManager } from '../../../../manager/ShareManager';
import { systemDateTime } from '@kit.BasicServicesKit';
import { SaveUtils } from '../../../../utils/SaveUtils';
import { DownloadDialog, DownloadStatus } from '../../../../dialog/DownloadDialog';
import { EventConstants } from '../../../../common/EventConstants';
import { SimpleTipDialog } from '../../../../dialog/SimpleTipDialog';
import { EventReportGlobalManager } from '../../../../manager/EventReportGlobalManager';
import { PasteboardUtils } from '../../../../utils/PasteboardUtils';
import { TipDialog } from '../../../../dialog/TipDialog';
import { PrefUtils } from '../../../../utils/PrefUtils';

@Entry
@ComponentV2
struct TakeMaterialPage {
  @Local inputText: string = '';
  @Local currentIndex: number = 0;

  @Local materialInfo?: MaterialInfoEntity;

  @Local videoList: Array<VideoMaterial> = [];
  @Local imageList: Array<ImageMaterial> = [];
  @Local audioList: Array<AudioMaterial> = [];
  @Local textList: Array<TextMaterial> = [];

  @Local videoRowCount: number = 1;
  @Local imageRowCount: number = 1;

  viewModel: TakeMaterialViewModel = new TakeMaterialViewModel(this.getUIContext());

  tabController: TabsController = new TabsController();
  titles: Array<string> = ['视频', '图片', '音频', '文本'];
  logId?: string;
  type: number = 0
  originText: string = ''

  mediaDownloader?: MediaDownloader | null
  selectedList: Array<MediaEntity> = []
  cacheFileUris: Array<string>  = []
  downloadIndex: number = 0
  totalSize = 0
  downloadStatus = DownloadStatus.DOWNLOADING

  @Monitor('viewModel.materialInfo')
  onMaterialInfoChange(monitor: IMonitor) {
    const info = monitor.value()?.now as MaterialInfoEntity
    this.logId = info.logid;
    MaterialLoadingDialog.show(this.getUIContext(), info.status_name)
    this.viewModel.analysisMaterial(info.logid, info.timeout);
  }

  @Monitor('viewModel.analysisInfo')
  onAnalysisInfoInfoChange(monitor: IMonitor) {
    const info = monitor.value()?.now as MaterialInfoEntity
    if (info.material && info.material !== null) {
      this.materialInfo = info;
      this.originText = this.inputText
      this.materialInfo.logid = this.logId!!
      this.createVideoList(info.material);
      this.createImageList(info.material);
      this.createAudioList(info.material);
      this.createTextList(info.material);
      if (this.videoList.length > 0) {
        this.tabController.changeIndex(0);
      } else if (this.imageList.length > 0) {
        this.tabController.changeIndex(1);
      }
      MaterialLoadingDialog.dismiss();
    } else {
      if (info.status !== 1) {
        ToastUtils.show(info.status_name)
        MaterialLoadingDialog.dismiss()
      } else {
        MaterialLoadingDialog.update(info.status_name)
      }
    }
  }

  @Monitor('viewModel.permissionInfo')
  onPermissionInfoChange(monitor: IMonitor) {
    const info = monitor.value()?.now as VipPermissionEntity;
    if (info.auth) {
      if (!LoginManager.isLogin()) {
        this.getUIContext().getRouter().pushUrl({url: RouterUrls.LOGIN_PAGE, params: {from: 1}}, router.RouterMode.Single)
        return;
      }
      this.shareOrDownload()
    } else {
      if (!info.auth_ad) {
        this.getUIContext().getRouter().pushUrl({url: RouterUrls.VIP_PAGE, params: {origin: 'download_material'}})
        EventReportGlobalManager.eventReport(EventConstants.JUMP_TO_MEMBER_RECHARGE, 'download_material')
        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});
      EventReportGlobalManager.eventReport(EventConstants.JUMP_TO_RECHARGE_DIAMOND, 'download_material')
      ToastUtils.show('M币已用完')
    }
  }

  aboutToAppear(): void {
    const params = this.getUIContext().getRouter().getParams() as Record<string, Object>
    if (params && params.url) {
      this.inputText = params.url as string
      this.parseUrl(this.inputText)
    }
  }

  aboutToDisappear(): void {
    this.viewModel.cancelInterval()
  }

  onPageShow(): void {
    this.checkPasteboard()
  }

  checkPasteboard() {
    PasteboardUtils.isNeedGetPermissionFromUser()
      .then((isNeed) => {
        if (isNeed) {
          PasteboardUtil.requestPermissions()
            .then((isGranted) => {
              if (isGranted) {
                let content = PasteboardUtil.getDataTextSync()
                if (StrUtil.isNotEmpty(content) && content !== PasteboardUtils.clipText && PasteboardUtils.isValidUrl(content)) {
                  TipDialog.show(this.getUIContext(), {title: '您已复制链接，是否粘贴', content: content, leftText: '取消', rightText: '粘贴', callback: {
                    confirm: () => {
                      PasteboardUtils.clipText = content
                      this.inputText = content
                      this.parseUrl(content)
                    },
                    cancel: () => {
                      PasteboardUtils.clipText = content
                    }
                  }})
                }
              }
            })
            .catch(() => {})
        }
      })
  }

  showSaveTip(isAudio: boolean = false) {
    if (!isAudio) {
      if (PrefUtils.getBoolean('show_save_tip', true)) {
        SimpleTipDialog.show(this.getUIContext(), {title: '重要提示', content: '下载完成后需要您点击弹窗允许保存之后才能保存文件到相册', callback: {
          confirm: () => {
            this.viewModel.checkVip();
            PrefUtils.put('show_save_tip', false)
          }
        }})
      } else {
        this.viewModel.checkVip();
      }
    } else {
      this.viewModel.checkVip();
    }
  }

  shareOrDownload() {
    this.cacheFileUris.length = 0
    if (this.type == 0) {
      if (this.selectedList.length > 0) {
        this.shareMedia(this.selectedList[0])
      }
    } else {
      if (this.selectedList.length > 0) {
        this.downloadIndex = 0
        this.downloadMedia(this.selectedList[this.downloadIndex])
      }
    }
  }

  shareMedia(media: MediaEntity) {
    let filePath = FileUtil.getCacheDirPath() + FileUtil.separator + media.initFileName()
    if (FileUtil.accessSync(filePath) && FileUtil.isFile(filePath) && !(media.totalSize === 0 || media.currentLen !== media.totalSize)) {
      this.shareFile(media)
    } else {
      this.showDownloadDialog(media instanceof VideoMaterial && media.isMerge ? DownloadStatus.VIDEO_DOWNLOADING : DownloadStatus.DOWNLOADING)
      if (media.isMerge) {
        this.beforeDoMerge(media)
      }
      this.download(media, true)
    }
  }

  async downloadMedia(media: MediaEntity) {
    let filePath = FileUtil.getCacheDirPath() + FileUtil.separator + media.initFileName()
    if (FileUtil.accessSync(filePath) && FileUtil.isFile(filePath) && !(media.totalSize === 0 || media.currentLen !== media.totalSize)) {
      this.cacheFileUris.push(FileUtil.getUriFromPath(filePath))
      if (this.downloadIndex < this.selectedList.length - 1) {
        this.downloadIndex++
        this.downloadMedia(this.selectedList[this.downloadIndex])
      } else {
        let saved = await this.saveFile(media)
        if (saved) {
          if (this.downloadIndex < this.selectedList.length - 1) {
            this.downloadIndex++
            this.downloadMedia(this.selectedList[this.downloadIndex])
          } else {
            this.updateDownloadDialog(DownloadStatus.COMPLETED, this.totalSize, this.totalSize, media instanceof AudioMaterial)
          }
        } else {
          ToastUtils.show('保存失败')
          this.dismissDownloadDialog()
        }
      }
    } else {
      this.showDownloadDialog(media instanceof VideoMaterial && media.isMerge ? DownloadStatus.VIDEO_DOWNLOADING : DownloadStatus.DOWNLOADING)
      if (media.isMerge) {
        this.beforeDoMerge(media)
      }
      this.download(media)
    }
  }

   beforeDoMerge(media: MediaEntity) {
     let video = media as VideoMaterial
     let audio = video.audio
     let name = systemDateTime.getTime()
     if (StrUtil.isEmpty(video.cacheName)) video.cacheName = `merge_${name}.mp4`
     if (audio && StrUtil.isEmpty(audio?.cacheName)) audio.cacheName = `merge_${name}.mp3`
  }

  async download(media: MediaEntity, isShare: boolean = false) {
    this.viewModel.reportStatus(this.materialInfo!!.logid, '1')
    media.initFileName()
    media.origin = this.originText
    this.mediaDownloader = MediaDownloader.getInstance()
    this.mediaDownloader.setProxyList(this.materialInfo?.material?.proxyUrlList)
      .callback({
        onSuccess: async (path) => {
          if (isShare) {
            this.shareFile(media)
          } else {
            this.cacheFileUris.push(FileUtil.getUriFromPath(path))
            if (this.downloadIndex < this.selectedList.length - 1) {
              this.downloadIndex++
              this.downloadMedia(this.selectedList[this.downloadIndex])
            } else {
              let saved = await this.saveFile(media)
              if (saved) {
                if (this.downloadIndex < this.selectedList.length - 1) {
                  this.downloadIndex++
                  this.downloadMedia(this.selectedList[this.downloadIndex])
                } else {
                  this.updateDownloadDialog(DownloadStatus.COMPLETED, this.totalSize, this.totalSize, media instanceof AudioMaterial)
                }
              } else {
                ToastUtils.show('保存失败')
                this.dismissDownloadDialog()
              }
            }
          }
        },
        onGetTotal: (total) => {
          this.totalSize = total
          this.updateDownloadDialog(this.downloadStatus, total)
        },
        onProgress: (progress) => {
          this.updateDownloadDialog(this.downloadStatus, this.totalSize, progress)
        },
        onMerge: (step) => {
          if (step === 4) {
            this.updateDownloadDialog(DownloadStatus.AUDIO_DOWNLOADING)
          } else {
            this.updateDownloadDialog(DownloadStatus.PROCESSING)
          }
        },
        onPause:() => {
          this.dismissDownloadDialog()
        },
        onCancel: () => {
          this.dismissDownloadDialog()
        },
        onFailed: (msg) => {
          ToastUtils.show('下载失败：' + msg)
          this.dismissDownloadDialog()
          this.viewModel.reportStatus(this.materialInfo!!.logid, '-1', `${media.totalSize}`, msg)
          this.reportErrorEvent(media, msg)
        }
      })
      .down(media);
  }

  shareFile(media: MediaEntity) {
    ShareManager.shareFile(FileUtil.getCacheDirPath() + FileUtil.separator + media.initFileName())
    this.viewModel.reportStatus(this.materialInfo!!.logid, '2', `${media.totalSize}`)
    this.dismissDownloadDialog()
  }

  async saveFile(media: MediaEntity): Promise<boolean> {
    let saved = false
    if (media instanceof VideoMaterial) {
      saved = await SaveUtils.saveImageVideoToAlbumDialog(this.cacheFileUris)
    } else if (media instanceof ImageMaterial) {
      saved = await SaveUtils.saveImageVideoToAlbumDialog(this.cacheFileUris)
    } else if (media instanceof AudioMaterial) {
      saved = await SaveUtils.saveAudioToMusic(this.cacheFileUris)
    }
    if (saved) {
      let totalSize = 0
      this.cacheFileUris.forEach((uri) => {
        let stat = FileUtil.statSync(FileUtil.getFilePath(uri))
        totalSize += stat.size
      })
      this.viewModel.reportStatus(this.materialInfo!!.logid, '2', `${totalSize}`)
    } else {
      this.viewModel.reportStatus(this.materialInfo!!.logid, '-1', `保存失败`)
    }
    return Promise.resolve(saved)
  }

  showDownloadDialog(status: DownloadStatus = DownloadStatus.DOWNLOADING) {
    this.downloadStatus = status
    DownloadDialog.show(this.getUIContext(), { status: status, totalSize: 0, progress: 0, totalCount: this.selectedList.length, index: this.downloadIndex, callback: {
      confirm: () => {
        if (this.downloadStatus === DownloadStatus.COMPLETED) {
          EventReportGlobalManager.eventReport(EventConstants.DIALOG_GO_TO_VIEW, this.titles[this.currentIndex])
          AppUtil.getContext().eventHub.emit(EventConstants.JumpToRecordEvent, this.currentIndex)
          this.getUIContext().getRouter().back()
        } else {
          //todo 后台下载
        }
      },
      cancel: () => {
        if (this.downloadStatus !== DownloadStatus.COMPLETED) {
          if (this.mediaDownloader) {
            this.mediaDownloader.cancel()
            EventReportGlobalManager.eventReport(EventConstants.CANCEL_DOWNLOAD_VIDEO, this.selectedList[this.downloadIndex].url)
          }
        } else {
          EventReportGlobalManager.eventReport(EventConstants.DIALOG_CONFIRM_SAVE_FILE, this.titles[this.currentIndex])
        }
      }
    } })
  }

  updateDownloadDialog(status: DownloadStatus = DownloadStatus.DOWNLOADING, totalSize: number = 0, progress: number = 0, isAudio: boolean = false) {
    this.downloadStatus = status
    DownloadDialog.update({ status: status, totalSize: totalSize, progress: progress, totalCount: this.selectedList.length, index: this.downloadIndex, isAudio: isAudio })
  }

  dismissDownloadDialog() {
    this.downloadStatus = DownloadStatus.DOWNLOADING
    this.totalSize = 0
    this.downloadIndex = 0
    this.mediaDownloader = null
    DownloadDialog.dismiss()
  }

  parseUrl(url: string) {
    if (StrUtil.isNotEmpty(this.inputText)) {
      this.viewModel.getMaterialInfo(url);
    }
  }

  createVideoList(material?: MaterialDetailEntity) {
    const list = new Array<VideoMaterial>();
    material?.video?.forEach((item, index) => {
      item.isThreading = material?.threading!!;
      if (material?.merge && material.audio && material.audio.length > index) {
        item.audio = material.audio[index];
        item.isMerge = true;
      }
      if (material?.image && material.image.length > index) {
        item.thumb = material.image[index].url;
      }
      list.push(item);
    })
    this.videoList = list.map(item => ObjectUtil.assign(new VideoMaterial(), item) as VideoMaterial);
    if (this.videoList.length > 0) {
      this.videoList[0].isChecked = true
    }
    this.videoRowCount = this.computeRowCount(this.videoList);
  }

  createImageList(material: MaterialDetailEntity) {
    if (material.image) {
      this.imageList = material.image.map(item => ObjectUtil.assign(new ImageMaterial(), item) as ImageMaterial);
      if (this.imageList.length > 0) {
        this.imageList[0].isChecked = true
      }
      this.imageRowCount = this.computeRowCount(this.imageList);
    }
  }

  createAudioList(material: MaterialDetailEntity) {
    if (material.audio) {
      this.audioList = material.audio.map(item => ObjectUtil.assign(new AudioMaterial(), item) as AudioMaterial);
      if (this.audioList.length > 0) {
        this.audioList[0].isChecked = true
      }
    }
  }

  createTextList(material: MaterialDetailEntity) {
    const list = new Array<TextMaterial>();
    if (material.desc) {
      const text = new TextMaterial()
      text.title = material.title;
      text.desc = material.desc;
      list.push(text);
    }
    this.textList = list;
    if (this.textList.length > 0) {
      this.textList[0].isChecked = true
    }
  }

  computeRowCount(list: Array<MediaEntity>): number {
    if (list.length > 8) {
      return 3;
    } else if (list.length >= 3 && list.length <= 8) {
      return 2;
    } else {
      return 1;
    }
  }

  reportErrorEvent(media: MediaEntity, message: string) {
    if (media instanceof VideoMaterial) {
      EventReportGlobalManager.eventReport(EventConstants.ERROR_CLIENT_DOWNLOAD_VIDEO, media.url, message)
    } else if (media instanceof ImageMaterial) {
      EventReportGlobalManager.eventReport(EventConstants.ERROR_CLIENT_DOWNLOAD_IMG, media.url, message)
    } else if (media instanceof AudioMaterial) {
      EventReportGlobalManager.eventReport(EventConstants.ERROR_CLIENT_DOWNLOAD_AUDIO, media.url, message)
    }
  }

  build() {
    Column() {
      Row() {
        Button({ type: ButtonType.Circle, stateEffect: true }) {
          Image($r('app.media.ic_black_back')).width(24).height(24)
        }
        .width(40)
        .height(40)
        .margin({ left: 10 })
        .onClick(() => {
          this.getUIContext().getRouter().back()
        })
        .backgroundColor(Color.Transparent)

        Row() {
          Image($r('app.media.ic_link')).width(18).height(18)
          TextInput({ placeholder: '请输入链接地址', text: this.inputText })
            .layoutWeight(1)
            .fontColor($r('app.color.color_1a1a1a'))
            .fontSize(14)
            .placeholderColor($r('app.color.color_999999'))
            .placeholderFont({ size: 14 })
            .backgroundColor(Color.Transparent)
            .onChange((value: string) => {
              this.inputText = value;
            })
          Image($r('app.media.ic_clear_text'))
            .width(18)
            .height(18)
            .padding(2)
            .margin({right: 5})
            .visibility(StrUtil.isNotEmpty(this.inputText) ? Visibility.Visible : Visibility.None)
            .onClick(() => {
              this.inputText = '';
            })
          Button('获取', {type: ButtonType.Capsule ,stateEffect:true})
            .fontSize(14)
            .width(64)
            .height(32)
            .margin({right: 4})
            .backgroundColor($r('app.color.color_466afd'))
            .onClick(() => {
              if (StrUtil.isNotEmpty(this.inputText)) {
                KeyboardUtil.hide()
                this.parseUrl(this.inputText)
                EventReportGlobalManager.eventReport(EventConstants.GET_MATERIAL, "material-button", this.inputText)
              } else {
                ToastUtils.show('请输入链接地址')
              }
            })
        }
        .layoutWeight(1)
        .height(40)
        .borderRadius(20)
        .backgroundColor(Color.White)
        .margin({ left: 10, right: 16 })
        .padding({left: 10})
      }.height(100).padding({ top: 50 })

      Tabs({ barPosition: BarPosition.Start, controller: this.tabController }) {
        TabContent() {
          VideoMaterialPage({
            mediaList: this.videoList, rowCount: this.videoRowCount,
            onShare:(video) => {
              this.type = 0
              this.selectedList.length = 0
              this.selectedList.push(video)
              this.viewModel.checkVip();
            },
            onSave: (list) => {
              this.type = 1
              this.selectedList = list
              this.showSaveTip();
            } })
        }
        .tabBar(this.tabBuilder(this.titles[0], 0))

        TabContent() {
          ImageMaterialPage({
            mediaList: this.imageList, rowCount: this.imageRowCount,
            onShare:(image) => {
              this.type = 0
              this.selectedList.length = 0
              this.selectedList.push(image)
              this.viewModel.checkVip();
            },
            onSave: (list) => {
              this.type = 1
              this.selectedList = list
              this.showSaveTip();
            } })
        }
        .tabBar(this.tabBuilder(this.titles[1], 1))

        TabContent() {
          AudioMaterialPage({
            mediaList: this.audioList,
            onShare:(audio) => {
              this.type = 0
              this.selectedList.length = 0
              this.selectedList.push(audio)
              this.viewModel.checkVip();
            },
            onSave: (list) => {
              this.type = 1
              this.selectedList = list
              this.showSaveTip(true);
            } })
        }
        .tabBar(this.tabBuilder(this.titles[2], 2))

        TabContent() {
          TextMaterialPage({ mediaList: this.textList })
        }
        .tabBar(this.tabBuilder(this.titles[3], 3))
      }
      .scrollable(false)
      .onSelected((index: number) => {
        this.currentIndex = index;
      })
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.window_background'))
  }

  @Builder
  tabBuilder(title: string, targetIndex: number) {
    Stack() {
      if (this.currentIndex === targetIndex) {
        Image($r('app.media.ic_tab_indicator')).width(27).height(11).margin({top: 13})
      }
      Text(title)
        .fontColor(this.currentIndex === targetIndex ? $r("app.color.color_212226") : $r('app.color.color_5c5f6c'))
        .fontSize(this.currentIndex === targetIndex ? 16 : 14)
        .fontWeight(this.currentIndex === targetIndex ? FontWeight.Medium : FontWeight.Regular)
    }
    .width('100%')
    .height(50)
  }
}