/*
 * 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 { display, promptAction } from '@kit.ArkUI';
import { connection } from '@kit.NetworkKit';
import { DynamicsRouter, FoldableRouter } from 'routermodule';
import { getNWeb, getNWebEx, PlatformInfo, PlatformTypeEnum } from 'utils';
import { CollapseMenu } from 'collapsemenu';
import { SceneModuleInfo } from './model/SceneModuleInfo';
import { WaterFlowDataSource } from './model/WaterFlowDataSource';
import { TAB_DATA, TabDataModel } from './model/TabsData';
import { common, Want } from '@kit.AbilityKit';

/**
 * 瀑布流列表项组件布局
 *
 * @param listData 组件列表信息
 *
 * TODO:知识点:
 * 1.@Reusable标识自定义组件具备可复用的能力,它可以被添加到任意的自定义组件上。
 * 2.复用自定义组件时避免一切可能改变自定义组件的组件树结构和可能使可复用组件中产生重新布局的操作以将组件复用的性能提升到最高。
 */
@Reusable
@Component
struct methodPoints {
  @Consume itemWidth: number;
  @State listData: SceneModuleInfo = new SceneModuleInfo
  ($r("app.media.functional_scenes_address_exchange"), '地址交换动画', 'addressexchange/AddressExchangeView', '动效', 1)
  @State helperUrl: string = 'about://blank';
  @State screenW: number = px2vp(display.getDefaultDisplaySync().width);
  @State isNeedClear: boolean = false;
  @State @Watch("onShowReadMeChange") isShowReadMe: boolean = false;
  /*
   * 依据Navigation的mode属性说明,如使用Auto,窗口宽度>=600vp时,采用Split模式显示;窗口宽度<600vp时,采用Stack模式显示。
   * */
  private deviceSize: number = 600;

  aboutToAppear(): void {
    if (this.screenW >= this.deviceSize) {
      this.isNeedClear = true;
    } else {
      this.isNeedClear = false;
    }
  }

  /**
   * 组件的生命周期回调,在可复用组件从复用缓存中加入到组件树之前调用
   * @param params:组件更新时所需参数
   */
  aboutToReuse(params: Record<string, SceneModuleInfo>): void {
    this.listData = params.listData as SceneModuleInfo;
  }

  onShowReadMeChange(): void {
    if (!this.isShowReadMe) {
      // 半模态弹窗关闭时,加载空白页面,防止主页瀑布流源码页面显示混乱
      if (PlatformInfo.getPlatform() == PlatformTypeEnum.HARMONYOS) {
        getNWeb('about://blank')
      } else if (PlatformInfo.isArkUIX()) {
        getNWebEx('about://blank', this.getUIContext());
      }
    }
  }

  changeHelpUrl(): void {
    this.helperUrl = this.listData.helperUrl;
  }

  /*
   * 帮助功能:半模态弹窗显示对应案例README
   * */
  @Builder
  buildReadMeSheet(): void {
    Column() {
      Row() {
        Row() {
          Text(this.listData.name)
            .textOverflow({ overflow: TextOverflow.Clip })
            .fontColor(Color.White)
            .fontWeight(700)
            .fontSize($r('app.integer.nav_destination_title_text_size'))
        }
        .width($r('app.integer.readme_sheet_text_size'))

        Column() {
          Stack() {
            Column() {
            }
            .width($r('app.integer.readme_sheet_size'))
            .height($r('app.integer.readme_sheet_size'))
            .borderRadius($r('app.integer.nav_destination_title_image_border_radius'))
            .backgroundColor(Color.White)
            .opacity(0.05)

            Image($r('app.media.ic_public_cancel'))
              .fillColor(Color.White)
              .width($r('app.integer.readme_sheet_cancel_image_width'))
          }
        }
        .onClick(() => {
          this.isShowReadMe = false;
        })
        .justifyContent(FlexAlign.Center)
        .width($r('app.integer.readme_sheet_size'))
        .height($r('app.integer.readme_sheet_size'))
        .borderRadius($r('app.integer.nav_destination_title_image_border_radius'))
      }
      .padding({ left: $r('app.integer.readme_sheet_padding'), right: $r('app.integer.readme_sheet_padding') })
      .margin({ top: $r('app.integer.readme_sheet_margin'), })
      .justifyContent(FlexAlign.SpaceBetween)
      .width('100%')

      NodeContainer(
        PlatformInfo.getPlatform() == PlatformTypeEnum.HARMONYOS ?
        getNWeb(this.helperUrl) : getNWebEx(this.helperUrl, this.getUIContext())
      )
        .width('100%')
        .height('100%')
        .onAppear(() => {
          this.changeHelpUrl();
        })
    }
    .width('100%')
    .height('100%')
  }

  build() {
    Column() {
      Image(this.listData.imageSrc)
        .borderRadius({
          topLeft: $r('app.string.functional_scenes_main_page_list_borderRadius'),
          topRight: $r('app.string.functional_scenes_main_page_list_borderRadius'),
          bottomLeft: 0,
          bottomRight: 0
        })
        .objectFit(ImageFit.Contain)
        .width('100%')
      Text(this.listData.serialNumber.toString() + '. ' + this.listData.name)
        .padding({
          left: $r('app.string.functional_scenes_main_page_padding6'),
          right: $r('app.string.functional_scenes_main_page_padding6')
        })
        .width('100%')
        .fontColor(Color.Black)
        .textAlign(TextAlign.Start)
        .maxLines(2)
        .fontSize($r('app.string.ohos_id_text_size_body1'))
        .margin({
          top: $r('app.string.functional_scenes_main_page_margin1'),
          bottom: $r('app.string.functional_scenes_main_page_margin1')
        })
        .textOverflow({ overflow: TextOverflow.Ellipsis })
      Row() {
        if (PlatformInfo.getPlatform() === PlatformTypeEnum.HARMONYOS) {
          Button() {
            Text($r('app.string.functional_scenes_readme'))
              .fontSize($r('app.integer.functional_scenes_readme_font_size'))
              .fontColor(Color.White)
          }
          .height($r('app.integer.functional_scenes_readme_height'))
          .width($r('app.integer.functional_scenes_readme_width'))
          .margin({ right: 10 })
          .gesture(
            GestureGroup(
              GestureMode.Exclusive,
              TapGesture({ fingers: 1, count: 1 })
                .onAction(() => {
                  connection.hasDefaultNet().then((res: boolean) => {
                    if (res) {
                      this.isShowReadMe = !this.isShowReadMe;
                    } else {
                      promptAction.showToast({ message: $r("app.string.functional_scenes_network_message") });
                    }
                  });
                })
            )
          )
          .bindSheet($$this.isShowReadMe, this.buildReadMeSheet(), {
            detents: [SheetSize.MEDIUM, SheetSize.LARGE],
            showClose: false,
            dragBar: true,
            backgroundColor: $r("app.color.helper_bindsheet_bgc"),
            preferType: SheetType.CENTER,
            // 设置为false时不允许与背景页面交互,显示蒙层
            enableOutsideInteractive: false,
            // 设置半模态高度变化过程中持续更新内容
            scrollSizeMode: ScrollSizeMode.CONTINUOUS
          })
        }

        Text($r('app.string.functional_scenes_difficulty'))
          .fontColor(Color.Black)
          .opacity(0.6)
          .textAlign(TextAlign.Start)
          .maxLines(1)
          .height($r('app.string.functional_scenes_main_page_text_height'))
          .fontSize($r('app.string.functional_scenes_main_page_text_font_size'))
          .width($r('app.string.functional_scenes_main_page_text_width'))
        Rating({
          rating: this.listData.ratingNumber,
          indicator: true
        })
          .stars(5)
          .width($r('app.integer.functional_scenes_rating_width'))
      }
      .padding({ left: 6 })
      .margin({ bottom: $r('app.string.functional_scenes_main_page_padding6') })
      .width($r('app.string.functional_scenes_full_size'))
      .justifyContent(FlexAlign.Start)
    }
    .shadow(ShadowStyle.OUTER_DEFAULT_XS)
    .backgroundColor(Color.White)
    .width(this.itemWidth)
    .borderRadius($r('app.string.functional_scenes_main_page_list_borderRadius'))
    .margin({
      top: $r('app.string.functional_scenes_item_gap_half'),
      bottom: $r('app.string.functional_scenes_item_gap_half')
    })
    .onClick(() => {
      console.log(`scenes item click in ${this.listData.appUri}`)
      if (this.listData.appUri === 'secondfloorloadanimation/SecondFloorLoadAnimation') {
        const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
        let want: Want= {
          bundleName: 'com.north.cases',
          moduleName: 'phone',
          abilityName: 'EntryAbility',
          parameters: { url: 'secondfloorloadanimation/SecondFloorLoadAnimation'}
        }
        context.startAbility(want, (err, data) => {
          console.log(`SecondFloorLoadAnimation startAbility err ${err}`);
        })
        return;
      }
      // 判断当前路由栈最后一个路由是否与当前跳转路由相同,相同则不跳转
      if (DynamicsRouter.appRouterStack.slice(-1)[0].name === this.listData.appUri) {
        return;
      }
      // 平板采用点击切换案例,需要pop,手机则不需要,左滑时已pop。
      if (this.isNeedClear) {
        DynamicsRouter.clear();
      }
      if (this.listData !== undefined) {
        // 点击瀑布流Item时,根据点击的模块信息,将页面放入路由栈
        FoldableRouter.pushUri(this.listData.appUri, this.listData.param);
      }
    })
  }
}

/**
 * 主页瀑布流列表
 */
@Component
export struct FunctionalScenes {
  @Link listData: SceneModuleInfo[];
  dataSource: WaterFlowDataSource = new WaterFlowDataSource(this.listData);
  @State tabsIndex: number = 0;
  @State tabColumns: string = '1fr 1fr';
  tabsController: TabsController = new TabsController();
  private scrollController: Scroller = new Scroller();
  isFoldable: boolean | undefined = AppStorage.get('isFoldable');
  @Provide itemWidth: number = 0

  aboutToAppear(): void {
    // 34为左右边距+两个瀑布流中间的距离
    this.itemWidth = (AppStorage.get('windowsWidth') as number - 34) / 2
  }

  @Builder
  tabBuilder(index: number, name: string | undefined) {
    Stack() {
      Column() {
      }
      .width(this.tabsIndex === index ? $r('app.integer.functional_scenes_tab_bar_background_width1') :
      $r('app.integer.functional_scenes_tab_bar_background_width2'))
      .backgroundColor(this.tabsIndex === index ? '#0A59F7' : '#000000')
      .opacity(this.tabsIndex === index ? 1 : 0.05)
      .height($r('app.integer.functional_scenes_tab_bar_background_height'))
      .borderRadius($r('app.integer.functional_scenes_tab_bar_background_border_radius'))

      Text(name)
        .fontSize($r('app.string.ohos_id_text_size_body1'))
        .fontColor(this.tabsIndex === index ? Color.White : Color.Black)
        .opacity(this.tabsIndex === index ? 1 : 0.8)
        .height('100%')
        .id('section')
    }
    .margin(index !== 0 && index !== TAB_DATA.length ? { left: $r('app.integer.functional_scenes_tab_bar_margin') } : {
      left: 0,
      right: 0
    })
    .align(Alignment.Center)
    .onClick(() => {
      this.tabsIndex = index;
      this.tabsController.changeIndex(index);
    })
  }

  @Builder
  tabsMenu() {
    Menu() {
      ForEach(TAB_DATA, (item: TabDataModel) => {
        MenuItem({ content: item.navData })
          .onClick(() => {
            this.tabsIndex = item.id;
            this.tabsController.changeIndex(item.id);
          })
          .id('menu_item')
      })
    }
  }

  /**
   * 主页通过瀑布流和LazyForeach加载
   * WaterFlow+LazyForEach详细用法可参考性能范例:
   * https://docs.openharmony.cn/pages/v4.0/zh-cn/application-dev/performance/waterflow_optimization.md/
   */
  build() {
    Column() {
      Row() {
        Stack() {
          List({ scroller: this.scrollController }) {
            ForEach(TAB_DATA, (tabItem: TabDataModel) => {
              ListItem() {
                this.tabBuilder(tabItem.id, tabItem.navData);
              }
            })
          }
          .id("MainList")
          .margin({ top: $r('app.integer.functional_scenes_tab_bar_list_margin') })
          .height($r('app.integer.functional_scenes_tab_bar_list_height'))
          .listDirection(Axis.Horizontal)
          .padding({ right: $r('app.integer.functional_scenes_tab_bar_list_padding') })
          .scrollBar(BarState.Off)

          Row() {
            Row() {
              Image($r('app.media.ic_public_more'))
                .width($r('app.integer.functional_scenes_tab_bar_image_more'))
                .id('mainPageTabsImage')
            }
            .bindMenu(this.tabsMenu)
            .justifyContent(FlexAlign.Center)
            .width($r('app.integer.functional_scenes_tab_bar_image_more_background_size'))
            .height($r('app.integer.functional_scenes_tab_bar_image_more_background_size'))
            .borderRadius($r('app.integer.functional_scenes_tab_bar_image_more_border_radius'))
            .backgroundColor('#D8D8D8')
            .id('menu_button')
          }
          .linearGradient({
            angle: 90,
            colors: [['rgba(241, 241, 241, 0)', 0], ['#F1F3F5', 0.2], ['#F1F3F5', 1]]
          })
          .justifyContent(FlexAlign.End)
          .width($r('app.integer.functional_scenes_tab_bar_image_more_row_width'))
          .height($r('app.integer.functional_scenes_tab_bar_image_more_row_height'))
        }
        .alignContent(Alignment.TopEnd)
      }
      .padding({
        left: $r('app.integer.functional_scenes_tab_bar_image_more_row_padding'),
        right: $r('app.integer.functional_scenes_tab_bar_image_more_row_padding')
      })
      .margin({ top: $r('app.integer.functional_scenes_tab_bar_image_more_row_margin') })

      Tabs({ controller: this.tabsController }) {
        ForEach(TAB_DATA, (tabItem: TabDataModel) => {
          TabContent() {
            if (tabItem.navData !== '性能文章') {
              WaterFlow() {
                LazyForEach(this.dataSource, (waterFlowItem: SceneModuleInfo) => {
                  FlowItem() {
                    if (tabItem.navData === '全部' || tabItem.navData === waterFlowItem.category) {
                      methodPoints({ listData: waterFlowItem })
                    }
                  }
                }, (waterFlowItem: SceneModuleInfo) => JSON.stringify(waterFlowItem))
              }
              .nestedScroll({
                scrollForward: NestedScrollMode.PARENT_FIRST,
                scrollBackward: NestedScrollMode.SELF_FIRST
              })
              .cachedCount(1)
              .columnsTemplate(this.tabColumns)
              .columnsGap($r('app.string.functional_scenes_main_page_water_flow_gap'))
              .width('100%')
              .clip(false)
              .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
              .padding({ bottom: $r('app.integer.functional_scenes_water_flow_padding_bottom') })
            } else {
              Scroll() {
                CollapseMenu()
              }
              .nestedScroll({
                scrollForward: NestedScrollMode.PARENT_FIRST,
                scrollBackward: NestedScrollMode.SELF_FIRST
              })
              .scrollBar(BarState.Off)
              .clip(false)
              .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
              .padding({ bottom: $r('app.integer.functional_scenes_water_flow_padding_bottom') })
            }
          }
          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
          .align(Alignment.TopStart)
          .alignSelf(ItemAlign.Start)
        })
      }
      .margin({ top: $r('app.integer.functional_scenes_tab_bar_image_more_row_margin') })
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
      .padding({
        left: $r('app.integer.functional_scenes_tab_bar_image_more_row_padding'),
        right: $r('app.integer.functional_scenes_tab_bar_image_more_row_padding')
      })
      .height('100%')
      .barWidth(0)
      .barHeight(0)
      .onAnimationStart((index: number, targetIndex: number) => {
        this.tabsIndex = targetIndex;
        this.scrollController.scrollToIndex(targetIndex, true, ScrollAlign.START);
      })
      .onAreaChange((_oldValue: Area, newValue: Area) => {
        if (_oldValue.width === newValue.width) {
          return;
        }
        /*
         * TODO:知识点:组件区域变化后根据窗口宽度计算瀑布流展示item列数
         * 根据屏幕宽度计算展示item列数
         * */
        let itemWidth = 177
        try {
          itemWidth = getContext(this).resourceManager.getNumber($r('app.integer.functional_scenes_item_width'));
        } catch (e) {
          console.log("resourceManager.getNumber error")
        }
        let maxItemCount = Math.floor(Number(newValue.width) / itemWidth);
        this.tabColumns = '1fr' + ' 1fr'.repeat(maxItemCount - 1);
      })
    }
    .height('100%')
    .backgroundColor("#F1F1F1")
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
  }
}