/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { ImageKnifeComponent, ImageKnifeData, ImageKnifeOption, ImageKnifeRequest } from '@ohos/libraryimageknife';
import { router } from '@kit.ArkUI';
import { PageViewModel } from './model/PageViewModel';

@Entry
@Component
struct TestImageKnifeCallbackPage {
  @State imageKnifeOption: ImageKnifeOption = {
    loadSrc: '',
    objectFit: ImageFit.Contain,
    border: { radius: 50 }
  };
  @State currentWidth: number = 200
  @State currentHeight: number = 200
  @State url: string | undefined = ''
  @State imageType: string | undefined = ''
  @State imageWidth: number | undefined = 0
  @State imageHeight: number | undefined = 0
  @State imageSize: number | undefined = 0
  @State componentWidth: number | undefined = 0
  @State componentHeight: number | undefined = 0
  @State frameNum: number | undefined = 0
  @State decodeSize: string | undefined = ''
  @State errMsg: string | undefined = ''
  @State errPhase: string | undefined = ''
  @State errCode: number | undefined = 0
  @State httpCode: number | undefined = 0
  @State reqStartTime: string | undefined = ''
  @State reqEndTime: string | undefined = ''
  @State reqCancelTime: string | undefined = ''
  @State memoryStartTime: string | undefined = ''
  @State memoryEndTime: string | undefined = ''
  @State diskStartTime: string | undefined = ''
  @State diskEndTime: string | undefined = ''
  @State netStartTime: string | undefined = ''
  @State netEndTime: string | undefined = ''
  @State decodeStartTime: string | undefined = ''
  @State decodeEndTime: string | undefined = ''
  @State showChild: boolean = true;
  @State requestFrom: string = '';

  build() {
    Column() {
      Text($r('app.string.img_url', this.url)).fontSize(14)
      Text($r('app.string.img_format', this.imageType)).fontSize(14)
      Text($r('app.string.img_master_size', this.imageWidth, this.imageHeight, this.imageSize)).fontSize(14)
      Text($r('app.string.componentWH', this.componentWidth, this.componentHeight)).fontSize(14)
      Text($r('app.string.img_frame', this.frameNum)).fontSize(14)
      Text($r('app.string.img_content_size', this.decodeSize)).fontSize(14)
      Text($r('app.string.err_msg', this.errMsg)).fontSize(14)
      Text($r('app.string.err_phase', this.errPhase)).fontSize(14)
      Text($r('app.string.err_code', this.errCode)).fontSize(14)
      Text($r('app.string.http_code', this.httpCode)).fontSize(14)
      Text($r('app.string.req_start_time', this.reqStartTime)).fontSize(14)
      Text($r('app.string.req_end_time', this.reqEndTime)).fontSize(14)
      Text($r('app.string.req_cancel_time', this.reqCancelTime)).fontSize(14)
      Text($r('app.string.memory_start_time', this.memoryStartTime)).fontSize(14)
      Text($r('app.string.memory_end_time', this.memoryEndTime)).fontSize(14)
      Text($r('app.string.disk_start_time', this.diskStartTime)).fontSize(14)
      Text($r('app.string.disk_end_time', this.diskEndTime)).fontSize(14)
      Text($r('app.string.net_start_time', this.netStartTime)).fontSize(14)
      Text($r('app.string.net_end_time', this.netEndTime)).fontSize(14)
      Text($r('app.string.decode_start_time', this.decodeStartTime)).fontSize(14)
      Text($r('app.string.decode_end_time', this.decodeEndTime)).fontSize(14)
      Text($r('app.string.request_data_from', this.requestFrom)).fontSize(14)

      Scroll() {
        Column() {

          Row() {
            Button($r('app.string.Network_images'))
              .fontSize(13)
              .onClick(() => {
                this.destroy();
                this.imageKnifeOption = {
                  loadSrc: PageViewModel.getMenus()[0],
                  objectFit: ImageFit.Contain,
                  onLoadListener: {
                    onLoadStart: (data) => {
                      this.analyzeStartCallBackData(data);
                    },
                    onLoadFailed: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    },
                    onLoadSuccess: (data, imageData, req) => {
                      this.analyzeSuccessCallBackData(req?.imageKnifeData);
                    },
                    onLoadCancel: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    }
                  },
                  border: { radius: 50 },
                }
              })

            Button($r('app.string.gif'))
              .fontSize(13)
              .onClick(() => {
                this.destroy();
                this.imageKnifeOption = {
                  loadSrc: PageViewModel.getGifMenus()[0],
                  objectFit: ImageFit.Contain,
                  onLoadListener: {
                    onLoadStart: (data) => {
                      this.analyzeStartCallBackData(data);
                    },
                    onLoadFailed: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    },
                    onLoadSuccess: (data, imageData, req) => {
                      this.analyzeSuccessCallBackData(req?.imageKnifeData);
                    },
                    onLoadCancel: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    }
                  },
                  border: { radius: 50 },
                }
              })
            Button($r('app.string.local_pic'))
              .fontSize(13)
              .onClick(() => {
                this.destroy();
                this.imageKnifeOption = {
                  loadSrc: $r('app.media.pngSample'),
                  objectFit: ImageFit.Contain,
                  onLoadListener: {
                    onLoadStart: (data) => {
                      this.analyzeStartCallBackData(data);
                    },
                    onLoadFailed: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    },
                    onLoadSuccess: (data, imageData, req) => {
                      this.analyzeSuccessCallBackData(req?.imageKnifeData);
                    },
                    onLoadCancel: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    }
                  },
                  border: { radius: 50 },
                }
              })
          }

          Row() {
            Button($r('app.string.net_load_failed'))
              .fontSize(13)
              .onClick(() => {
                this.destroy();
                this.imageKnifeOption = {
                  loadSrc: PageViewModel.getMenus()[2],
                  objectFit: ImageFit.Contain,
                  onLoadListener: {
                    onLoadStart: (data) => {
                      this.analyzeStartCallBackData(data);
                    },
                    onLoadFailed: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    },
                    onLoadSuccess: (data, imageData, req) => {
                      this.analyzeSuccessCallBackData(req?.imageKnifeData);
                    },
                    onLoadCancel: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    }
                  },
                  border: { radius: 50 },
                }
              })

            Button($r('app.string.local_load_failed'))
              .fontSize(13)
              .onClick(() => {
                this.destroy();
                this.imageKnifeOption = {
                  loadSrc: 'app.media.xxx',
                  objectFit: ImageFit.Contain,
                  onLoadListener: {
                    onLoadStart: (data) => {
                      this.analyzeStartCallBackData(data);
                    },
                    onLoadFailed: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    },
                    onLoadSuccess: (data, imageData, req) => {
                      this.analyzeSuccessCallBackData(req?.imageKnifeData);
                    },
                    onLoadCancel: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    }
                  },
                  border: { radius: 50 },
                }
              })
            Button($r('app.string.share_load_failed'))
              .fontSize(13)
              .onClick(() => {
                this.destroy();
                this.imageKnifeOption = {
                  loadSrc: 'datashare://ssas',
                  objectFit: ImageFit.Contain,
                  onLoadListener: {
                    onLoadStart: (data) => {
                      this.analyzeStartCallBackData(data);
                    },
                    onLoadFailed: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    },
                    onLoadSuccess: (data, imageData, req) => {
                      this.analyzeSuccessCallBackData(req?.imageKnifeData);
                    },
                    onLoadCancel: (res, req) => {
                      this.analyzeFailedBackData(res, req?.imageKnifeData);
                    }
                  },
                  border: { radius: 50 },
                }
              })
          }

          Button($r('app.string.test_cancel_callback_btn'))
            .fontSize(13)
            .onClick(() => {
              this.destroy();
              this.imageKnifeOption = {
                loadSrc: PageViewModel.getMenus()[0],
                objectFit: ImageFit.Contain,
                onLoadListener: {
                  onLoadStart: (data) => {
                    this.showChild = false;
                    this.analyzeStartCallBackData(data);
                  },
                  onLoadFailed: (res, req) => {
                    this.analyzeFailedBackData(res, req?.imageKnifeData);
                  },
                  onLoadSuccess: (data, imageData, req) => {
                    this.analyzeSuccessCallBackData(req?.imageKnifeData);
                  },
                  onLoadCancel: (res, req) => {
                    this.analyzeFailedBackData(res, req?.imageKnifeData);
                  }
                },
                border: { radius: 50 },
              }
            })

          Button($r('app.string.list_pic'))
            .fontSize(13)
            .onClick(() => {
              router.push({
                url: 'pages/TestListImageKnifeCallbackPage',
              });
            })
          if (this.showChild) {
            ImageKnifeComponent(
              { imageKnifeOption: this.imageKnifeOption })
              .height(this.currentHeight)
              .width(this.currentWidth)
              .margin({ top: 20, bottom: 20 })

          }
        }
        .width('100%')
      }
    }.alignItems(HorizontalAlign.Start)
  }

  formatDate(time: number | undefined) {
    if (!time) {
      return;
    }
    let date = new Date(time);
    const year = date.getFullYear().toString()
    let month = (date.getMonth() + 1).toString()
    let day = date.getDate().toString()
    let hour = date.getHours().toString()
    let min = date.getMinutes().toString()
    let seconds = date.getSeconds().toString()
    let mill = date.getMilliseconds();
    return `${year}-${month}-${day} ${hour}:${min}:${seconds}:${mill}`
  }

  analyzeStartCallBackData(req: ImageKnifeRequest | undefined) {
    let data = req?.imageKnifeData;
    if (data) {
      if (typeof req?.imageKnifeOption.loadSrc == 'string') {
        this.url = req?.imageKnifeOption.loadSrc;
      }
      this.componentWidth = req?.componentWidth;
      this.componentHeight = req?.componentHeight;
      this.reqStartTime = this.formatDate(data.timeInfo?.requestStartTime);
      this.memoryStartTime = this.formatDate(data.timeInfo?.memoryCheckStartTime);
      this.memoryEndTime = this.formatDate(data.timeInfo?.memoryCheckEndTime);
      this.requestFrom = '';
    }
  }

  analyzeSuccessCallBackData(data: ImageKnifeData | undefined) {
    if (data) {
      this.imageWidth = data.imageWidth;
      this.imageHeight = data.imageHeight;
      this.imageSize = data.bufSize;
      this.frameNum = data.frameCount;
      this.httpCode = data.httpCode
      this.decodeSize = JSON.stringify(data.decodeImages);
      this.imageType = data.type;
      this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
      this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
      this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
      this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
      this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
      this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
      this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
      if (data.timeInfo?.netRequestEndTime !== undefined) {
        this.requestFrom = 'Http request';
      } else if (data.timeInfo?.diskCheckEndTime !== undefined) {
        this.requestFrom = 'File Cache';
      } else {
        this.requestFrom = 'Memory Cache';
      }

    }
  }

  analyzeFailedBackData(res: string, data: ImageKnifeData | undefined) {
    if (data) {
      this.errMsg = res;
      this.errPhase = data.errorInfo?.phase;
      this.errCode = data.errorInfo?.code;
      this.httpCode = data.httpCode;
      this.reqEndTime = this.formatDate(data.timeInfo?.requestEndTime);
      this.diskStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
      this.diskEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
      this.netStartTime = this.formatDate(data.timeInfo?.netRequestStartTime);
      this.netEndTime = this.formatDate(data.timeInfo?.netRequestEndTime);
      this.decodeStartTime = this.formatDate(data.timeInfo?.diskCheckStartTime);
      this.decodeEndTime = this.formatDate(data.timeInfo?.diskCheckEndTime);
      this.reqCancelTime = this.formatDate(data.timeInfo?.requestCancelTime)
      this.requestFrom = '';
    }
  }

  destroy() {
    this.currentWidth = 200
    this.currentHeight = 200
    this.url = ''
    this.imageType = ''
    this.imageWidth = 0
    this.imageHeight = 0
    this.imageSize = 0
    this.componentWidth = 0
    this.componentHeight = 0
    this.frameNum = 0
    this.decodeSize = ''
    this.errMsg = ''
    this.errPhase = ''
    this.errCode = 0
    this.httpCode = 0
    this.reqStartTime = ''
    this.reqEndTime = ''
    this.reqCancelTime = ''
    this.memoryStartTime = ''
    this.memoryEndTime = ''
    this.diskStartTime = ''
    this.diskEndTime = ''
    this.netStartTime = ''
    this.netEndTime = ''
    this.decodeStartTime = ''
    this.decodeEndTime = ''
    this.showChild = true;
  }
}