/*
 * 消息列表页面
 * EZOpenSDK
 *
 * Created by junecheng on 2024/3/5.
 * Copyright (c) 2024年 Ezviz. All rights reserved.
 */

import router from '@ohos.router'
import { PullToRefresh, PullToRefreshConfigurator } from '@ohos/pulltorefresh'
import { EZAlarmInfo, EZOpenSDK, EZTimeUtil } from '@ohos/EZOpenSDK'

import EZToastUtil from '../../utils/EZToastUtil'
import RouterManager from '../../global/RouterManager/RouterManager'

import { NavigationView } from '../../global/view/NavigationView'
import VerifyCodeDialog from '../../global/view/VerifyCodeDialog'
import { MessageListCell } from './view/MessageListCell'

export default class EZMessageListRouterParam {
  deviceSerial: string

  constructor(deviceSerial: string) {
    this.deviceSerial = deviceSerial
  }
}

@Entry
@Component
export struct EZMessageListPage {
  private messageListPageSize: number = 20
  // 标题
  @State titleText: Resource = $r('app.string.dmessage_title')
  // 导航栏右上角文本
  @State editText: Resource = $r('app.string.dmessage_edit')
  // 当前是否是编辑模式
  @State isEditMode: boolean = false
  // 消息数组
  @State messageArr: Array<Array<EZAlarmInfo>> = []
  // 选中的消息数组
  @State selectArr: Array<Array<boolean>> = []
  private scroller: Scroller = new Scroller()
  private refreshConfigurator: PullToRefreshConfigurator = new PullToRefreshConfigurator()
  // 设备序列号
  private deviceSerial: string = ''
  // 当前页数
  private currentPageIndex: number = 0
  // 开始时间
  private beginTime: Date = new Date()
  // 结束时间
  private endTime: Date = new Date()
  // 是否还有更多数据
  private hasMoreMessage: boolean = true
  // 验证码输入框是否显示
  private isVerifyCodeShow: boolean = false

  // ------------------------ 生命周期 ------------------------

  aboutToAppear() {
    let routerParams = router.getParams() as EZMessageListRouterParam
    this.deviceSerial = routerParams?.deviceSerial

    EZTimeUtil.getCurrentTimeString()
    // 获取过去7天的告警消息，开发者可以自己设置时间范围。
    this.endTime = new Date()
    this.beginTime = EZTimeUtil.dateByAddingDays(this.endTime, 7)

    this.getUnreadMessageCount()
    this.getAlarmList(true)
    this.cancelAllSelectArr()
  }

  // ------------------------ 网络 ------------------------

  /** 获取未读消息总数 */
  getUnreadMessageCount() {
    EZOpenSDK.getUnreadMessageCount(this.deviceSerial, 1, (count, error) => {
      this.titleText = $r('app.string.dmessage_title', `（${count}）`)
    })
  }

  /** 获取消息列表 */
  getAlarmList(isRefresh: boolean): Promise<string> {
    if (isRefresh) {
      this.currentPageIndex = 0
    }
    return new Promise<string>((resolve) => {
      EZOpenSDK.getAlarmList(this.deviceSerial, this.currentPageIndex, this.messageListPageSize,
        this.beginTime, this.endTime, (alarmList, totalCount, error) => {
          if (error) {
            resolve((isRefresh ? $r('app.string.ez_refresh_fail') : $r('app.string.ez_load_fail')) + ' ' +
            EZTimeUtil.getCurrentTimeString())
          } else {
            resolve((isRefresh ? $r('app.string.ez_refresh_success') : $r('app.string.ez_load_success')) + ' ' +
            EZTimeUtil.getCurrentTimeString())
            if (alarmList !== null) {
              this.handleMessageList(alarmList, isRefresh)
              this.currentPageIndex++
              // 到顶了 不能加载更多
              this.hasMoreMessage = !(alarmList.length < this.messageListPageSize)
              this.refreshConfigurator.setHasLoadMore(this.hasMoreMessage)
            }
          }
        })
    })
  }

  /** 标记已读 */
  setAlarmStatus(alarmIds: string[], alarmStatus: number) {
    EZOpenSDK.setAlarmStatus(alarmIds, alarmStatus, (error) => {
      if (error) {
        EZToastUtil.showToast(error.message)
      } else {
        this.getUnreadMessageCount()
      }
    })
  }

  /** 删除 */
  deleteAlarm(alarmIds: string[]) {
    EZOpenSDK.deleteAlarm(alarmIds, (error) => {
      if (error) {
        EZToastUtil.showToast(error.message)
      } else {
        this.getUnreadMessageCount()
      }
    })
  }

  // ------------------------ ValidateCode Methods 验证码检验 ------------------------

  @State verifyCodeDialogInputContent: string = ''
  verifyCodeDialogController: CustomDialogController = new CustomDialogController({
    customStyle: true,
    builder: VerifyCodeDialog({
      deviceSerial: this.deviceSerial,
      title: $r('app.string.setting_device_security_check'),
      message: $r('app.string.setting_input_code_plz'),
      placeholder: $r('app.string.device_input_vierify_code'),
      inputContent: this.verifyCodeDialogInputContent,
      confirmClick: () => {
        this.isVerifyCodeShow = false
        // 输入密码后，刷新列表
        this.messageArr.push([])
        this.messageArr.splice(this.messageArr.length - 1, 1)
      },
      cancelClick: () => {
        this.isVerifyCodeShow = false
      }
    }),
    alignment: DialogAlignment.Center,
    autoCancel: false
  })

  // ------------------------ 自定义方法 ------------------------

  /*获取选中数量*/
  getSelectArrCount(): number {
    let totalNum = 0
    this.selectArr.forEach((elementArr) => {
      totalNum += elementArr.filter((selected: boolean) => selected === true).length
    })
    return totalNum
  }

  /*处理消息列表数据*/
  handleMessageList(alarmList: Array<EZAlarmInfo>, isRefresh: boolean) {
    if (isRefresh) {
      this.messageArr = []
    }
    alarmList.forEach(element => {
      let lastArrayM: Array<EZAlarmInfo> = []
      if (this.messageArr.length > 0) {
        lastArrayM = this.messageArr[this.messageArr.length-1]
      }
      if (lastArrayM.length === 0) {
        lastArrayM.push(element)
        this.messageArr.push(lastArrayM)
      } else if (EZTimeUtil.dateFormat(element.alarmStart, 'yyyy-MM-dd')
        == EZTimeUtil.dateFormat(lastArrayM[lastArrayM.length-1].alarmStart, 'yyyy-MM-dd')) {
        lastArrayM.push(element)
      } else {
        let arrayM: Array<EZAlarmInfo> = []
        arrayM.push(element)
        this.messageArr.push(arrayM)
      }
    })
  }

  /** 重置选中标记数组 */
  cancelAllSelectArr() {
    let newSelectArr: Array<Array<boolean>> = []
    this.messageArr.forEach((elementArr) => {
      let newInSelectArr: Array<boolean> = []
      elementArr.forEach(element => {
        newInSelectArr.push(false)
      })
      newSelectArr.push(newInSelectArr)
    })
    this.selectArr = newSelectArr
  }

  /** 删除选中项 */
  deleteSelectArr() {
    if (this.selectArr.length <= 0) {
      return
    }
    let selectedIndexArr: Array<Array<number>> = []
    let alarmIds: string[] = []
    this.selectArr.forEach((elementArr, outIndex) => {
      let selectInIndexArr: Array<number> = []
      elementArr.filter((seleted: boolean, index: number) => {
        if (seleted === true) {
          selectInIndexArr.push(index)
          alarmIds.push(this.messageArr[outIndex][index].alarmId)
        }
      })
      selectedIndexArr.push(selectInIndexArr)
    })
    selectedIndexArr.reverse().forEach((elementArr, reverseIndex) => {
      let index = selectedIndexArr.length - 1 - reverseIndex
      elementArr.reverse().forEach((inIndex) => {
        this.selectArr[index].splice(inIndex, 1)
        this.messageArr[index].splice(inIndex, 1)
      })
      if (this.selectArr[index].length === 0) {
        this.selectArr.splice(index, 1)
        this.messageArr.splice(index, 1)
      }
    })
    // 这里通过+-数组触发刷新
    this.messageArr.push([])
    this.messageArr.splice(this.messageArr.length - 1, 1)

    this.updateEditModeConfig(false)

    this.deleteAlarm(alarmIds)
  }

  /** 标记已读 */
  markReadedSelectArr() {
    if (this.selectArr.length <= 0) {
      return
    }
    let selectedIndexArr: Array<Array<number>> = []
    let alarmIds: string[] = []
    this.selectArr.forEach((elementArr, outIndex) => {
      let selectInIndexArr: Array<number> = []
      elementArr.filter((seleted: boolean, index: number) => {
        if (seleted === true) {
          selectInIndexArr.push(index)
          alarmIds.push(this.messageArr[outIndex][index].alarmId)
        }
      })
      selectedIndexArr.push(selectInIndexArr)
    })
    selectedIndexArr.reverse().forEach((elementArr, reverseIndex) => {
      let index = selectedIndexArr.length - 1 - reverseIndex
      elementArr.forEach((inIndex) => {
        let replaceObj: EZAlarmInfo = this.messageArr[index][inIndex]
        replaceObj.isChecked = true
        this.messageArr[index][inIndex] = replaceObj
      })
    })
    // state link监听有问题，数组内对象值变动，监听不到，导致无法刷新，API10禁用了Object.assign无法深拷贝，这里通过+-数组触发刷新
    this.messageArr.push([])
    this.messageArr.splice(this.messageArr.length - 1, 1)

    this.updateEditModeConfig(false)

    this.setAlarmStatus(alarmIds, 1)
  }

  /** 更新编辑模式下的配置 不可刷新 */
  updateEditModeConfig(isEditMode: boolean) {
    this.isEditMode = isEditMode
    this.editText = this.isEditMode ? $r('app.string.cancel') : $r('app.string.dmessage_edit')
    this.refreshConfigurator.setHasRefresh(!isEditMode)
    this.refreshConfigurator.setHasLoadMore(this.hasMoreMessage ? !isEditMode : false)
    this.cancelAllSelectArr()
  }

  // ------------------------ UI ------------------------

  build() {
    Flex({ direction: FlexDirection.Column }) {
      NavigationView({
        showRightBtn: true,
        title: this.titleText,
        rightNavTitle: this.editText,
        rightNavClick: () => {
          this.cancelAllSelectArr()
          this.updateEditModeConfig(!this.isEditMode)
        }
      })
      Stack({ alignContent: Alignment.Bottom }) {
        PullToRefresh({
          data: this.messageArr,
          scroller: this.scroller,
          customList: () => {
            this.MessageListView()
          },
          onAnimLoading: () => {
          },
          onRefresh: () => {
            return this.getAlarmList(true)
          },
          onLoadMore: () => {
            return this.getAlarmList(false)
          },
          customLoad: null,
          customRefresh: null,
          refreshConfigurator: this.refreshConfigurator
            .setMaxTranslate(60)
            .setRefreshTextSize(12)
            .setLoadTextSize(12)
            .setLoadTextLoading('正在加载更多的数据')
        })
          .height('100%')
        this.BottomSelectView()
      }
    }
  }

  @Builder
  MessageListView() {
    List({ scroller: this.scroller }) {
      ForEach(this.messageArr, (itemArr: Array<EZAlarmInfo>, index) => {
        this.MessageCellHeader(itemArr)
        ForEach(itemArr, (item: EZAlarmInfo, inIndex) => {
          ListItem() {
            MessageListCell({
              isEditMode: this.isEditMode,
              selectArr: $selectArr,
              alarmInfo: item,
              index: index,
              inIndex: inIndex,
              onCellClick: () => {
                if (this.isEditMode) {
                  this.selectArr[index][inIndex] = !this.selectArr[index][inIndex]
                  // 触发刷新
                  this.selectArr.push([])
                  this.selectArr.splice(this.selectArr.length - 1, 1)
                } else {
                  let replaceObj: EZAlarmInfo = this.messageArr[index][inIndex]
                  replaceObj.isChecked = true
                  this.messageArr[index][inIndex] = replaceObj
                  RouterManager.pushUrl(RouterManager.messagePhotoPage, this.messageArr[index][inIndex])
                  this.setAlarmStatus([replaceObj.alarmId], 1)
                  // 刷新
                  this.messageArr.push([])
                  this.messageArr.splice(this.messageArr.length - 1, 1)
                }
              },
              onVerifyCodeError: () => {
                if (!this.isVerifyCodeShow) {
                  this.verifyCodeDialogController.open()
                  this.isVerifyCodeShow = true
                }
              }
            })
          }
        })
      })
    }
    .edgeEffect(EdgeEffect.None)
  }

  @Builder
  MessageCellHeader(itemArr: Array<EZAlarmInfo>) {
    if (itemArr.length > 0) {
      Text('  ' + EZTimeUtil.dateFormat(itemArr[0].alarmStart, 'MM-dd'))
        .backgroundColor($r('app.color.message_cell_header_color'))
        .fontSize(14)
        .height(20).width('100%')
    }
  }

  @Builder
  BottomSelectView() {
    if (this.isEditMode) {
      Row() {
        Text($r('app.string.delete'))
          .fontSize(16)
          .onClick(() => {
            this.deleteSelectArr()
          })
        Text($r('app.string.message_read', this.getSelectArrCount() > 0 ? `${this.getSelectArrCount()}` : ''))
          .fontSize(16)
          .onClick(() => {
            this.markReadedSelectArr()
          })
      }
      .visibility(this.getSelectArrCount() > 0 ? Visibility.Visible : Visibility.Hidden)
      .padding({ left: 16, right: 16 })
      .height(60)
      .width('100%')
      .justifyContent(FlexAlign.SpaceBetween)
      .alignItems(VerticalAlign.Center)
      .backgroundColor(Color.White)
      .align(Alignment.BottomEnd)
    }
  }
}
