/*
 * Copyright (c) 2023-2023 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 { KeyCode } from '@ohos.multimodalInput.keyCode';
import window from '@ohos.window';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@kit.BasicServicesKit';
import hilog from '@ohos.hilog';

export interface ComposeTitleBarMenuItem {
  value: ResourceStr;
  symbolStyle?: SymbolGlyphModifier;
  isEnabled?: boolean;
  action?: () => void;
  label?: ResourceStr;
  accessibilityText?: ResourceStr;
  accessibilityLevel?: string;
  accessibilityDescription?: ResourceStr;
}

const PUBLIC_MORE: Resource = $r('sys.symbol.dot_grid_2x2');
const PUBLIC_BACK: Resource = $r('sys.symbol.arrow_left');
const TEXT_EDITABLE_DIALOG = '18.3fp';
const IMAGE_SIZE = '64vp';
const MAX_DIALOG = '256vp';
const MIN_DIALOG = '216vp';
const RESOURCE_TYPE_SYMBOL: number = 40000;

class Util {
  public static isSymbolResource(resourceStr: ResourceStr | undefined | null): boolean {
    if (!Util.isResourceType(resourceStr)) {
      return false;
    }
    let resource: Resource = resourceStr as Resource;
    return resource.type === RESOURCE_TYPE_SYMBOL;
  }

  public static isResourceType(resource: ResourceStr | Resource | undefined | null): boolean {
    if (!resource) {
      return false;
    }
    if (typeof resource === 'string' || typeof resource === 'undefined') {
      return false;
    }
    return true;
  }
}

class ButtonGestureModifier implements GestureModifier {
  public static readonly longPressTime: number = 500;
  public static readonly minFontSize: number = 1.75;
  public fontSize: number = 1;
  public controller: CustomDialogController | null = null;

  constructor(controller: CustomDialogController | null) {
    this.controller = controller;
  }

  applyGesture(event: UIGestureEvent): void {
    if (this.fontSize >= ButtonGestureModifier.minFontSize) {
      event.addGesture(
        new LongPressGestureHandler({ repeat: false, duration: ButtonGestureModifier.longPressTime })
          .onAction(() => {
            if (event) {
              this.controller?.open();
            }
          })
          .onActionEnd(() => {
            this.controller?.close();
          })
      )
    } else {
      event.clearGestures();
    }
  }
}

@Component
struct ComposeTitleBar {
  item: ComposeTitleBarMenuItem | undefined = undefined;
  title: ResourceStr = '';
  subtitle: ResourceStr = '';
  menuItems?: Array<ComposeTitleBarMenuItem> = [];
  @State titleMaxWidth: number = 0;
  @State fontSize: number = 1;
  private static readonly totalHeight = 56;
  private static readonly leftPadding = 12;
  private static readonly rightPadding = 12;
  private static readonly portraitImageSize = 40;
  private static readonly portraitImageLeftPadding = 4;
  private static readonly portraitImageRightPadding = 16;
  private static instanceCount = 0;
  @Provide('uniqueId') uniqueId?: number = -1;

  build() {
    Flex({
      justifyContent: FlexAlign.SpaceBetween,
      alignItems: ItemAlign.Stretch
    }) {
      Row() {
        ImageMenuItem({
          item: {
            value: PUBLIC_BACK,
            isEnabled: true,
            action: () => this.getUIContext()?.getRouter()?.back()
          },
          index: -1,
          itemIndex: -1
        })

        Row() {
          if (this.item !== undefined) {
            Image(this.item.value)
              .width(ComposeTitleBar.portraitImageSize)
              .height(ComposeTitleBar.portraitImageSize)
              .margin({
                left: $r('sys.float.ohos_id_text_paragraph_margin_xs'),
                right: $r('sys.float.ohos_id_text_paragraph_margin_m')
              })
              .focusable(false)
              .borderRadius(ImageMenuItem.buttonBorderRadius)
          }

          Column() {
            if (this.title !== undefined) {
              Row() {
                Text(this.title)
                  .fontWeight(FontWeight.Medium)
                  .fontSize($r('sys.float.ohos_id_text_size_headline8'))
                  .fontColor($r('sys.color.ohos_id_color_titlebar_text'))
                  .maxLines(this.subtitle !== undefined ? 1 : 2)
                  .textOverflow({ overflow: TextOverflow.Ellipsis })
                  .constraintSize({ maxWidth: this.titleMaxWidth })
              }
              .justifyContent(FlexAlign.Start)
            }
            if (this.subtitle !== undefined) {
              Row() {
                Text(this.subtitle)
                  .fontSize($r('sys.float.ohos_id_text_size_over_line'))
                  .fontColor($r('sys.color.ohos_id_color_titlebar_subtitle_text'))
                  .maxLines(1)
                  .textOverflow({ overflow: TextOverflow.Ellipsis })
                  .constraintSize({ maxWidth: this.titleMaxWidth })
              }
              .justifyContent(FlexAlign.Start)
            }
          }
          .justifyContent(FlexAlign.Start)
          .alignItems(HorizontalAlign.Start)
          .constraintSize({ maxWidth: this.titleMaxWidth })
        }
        .accessibilityGroup(true)
        .accessibilityDescription($r('sys.string.subheader_accessibility_title'))
      }
      .margin({ left: $r('sys.float.ohos_id_default_padding_start') })

      if (this.menuItems !== undefined && this.menuItems.length > 0) {
        CollapsibleMenuSection({ menuItems: this.menuItems, index: 1 + ComposeTitleBar.instanceCount++ })
      }
    }
    .onAppear(() => {
      try {
        this.uniqueId = this.getUIContext().getFrameNodeByUniqueId(this.getUniqueId())?.getFirstChild()?.getUniqueId();
      } catch (exception) {
        let code: number = (exception as BusinessError)?.code;
        let message: string = (exception as BusinessError)?.message;
        hilog.error(0x3900, 'ComposeTitleBar',
          `Faild to getFrameNodeByUniqueId,cause, code: ${code}, message: ${message}`);
      }
    })
    .width('100%')
    .height(ComposeTitleBar.totalHeight)
    .backgroundColor($r('sys.color.ohos_id_color_background'))
    .onAreaChange((_oldValue: Area, newValue: Area) => {
      let newWidth = Number(newValue.width);
      if (this.menuItems !== undefined) {
        let menusLength = this.menuItems.length;
        if (menusLength >= CollapsibleMenuSection.maxCountOfVisibleItems) {
          newWidth = newWidth - ImageMenuItem.imageHotZoneWidth * CollapsibleMenuSection.maxCountOfVisibleItems;
        } else if (menusLength > 0) {
          newWidth = newWidth - ImageMenuItem.imageHotZoneWidth * menusLength;
        }
      }
      this.titleMaxWidth = newWidth;
      this.titleMaxWidth -= ComposeTitleBar.leftPadding;
      this.titleMaxWidth -= ImageMenuItem.imageHotZoneWidth;
      if (this.item !== undefined) {
        this.titleMaxWidth -= ComposeTitleBar.portraitImageLeftPadding +
        ComposeTitleBar.portraitImageSize +
        ComposeTitleBar.portraitImageRightPadding;
      }
      this.titleMaxWidth -= ComposeTitleBar.rightPadding;
    })
  }
}

@Component
struct CollapsibleMenuSection {
  menuItems?: Array<ComposeTitleBarMenuItem> = [];
  item: ComposeTitleBarMenuItem = {
    value: PUBLIC_MORE,
    label: $r('sys.string.ohos_toolbar_more'),
  } as ComposeTitleBarMenuItem;
  index: number = 0;
  minFontSize: number = 1.75;
  isFollowingSystemFontScale: boolean = false;
  maxFontScale: number = 1;
  systemFontScale?: number = 1;
  static readonly maxCountOfVisibleItems = 3;
  private static readonly focusPadding = 4;
  private static readonly marginsNum = 2;
  private firstFocusableIndex = -1;
  @State isPopupShown: boolean = false;
  @State isMoreIconOnFocus: boolean = false;
  @State isMoreIconOnHover: boolean = false;
  @State isMoreIconOnClick: boolean = false;
  @Prop @Watch('onFontSizeUpdated') fontSize: number = 1;
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: ComposeTitleBarDialog({
      cancel: () => {
      },
      confirm: () => {
      },
      itemComposeTitleDialog: this.item,
      composeTitleBarDialog: this.item.label ? this.item.label : '',
      fontSize: this.fontSize,
    }),
    maskColor: Color.Transparent,
    isModal: true,
    customStyle: true,
  })

  @State buttonGestureModifier: ButtonGestureModifier = new ButtonGestureModifier(this.dialogController);

  getMoreIconFgColor() {
    return this.isMoreIconOnClick ?
    $r('sys.color.ohos_id_color_titlebar_icon_pressed') :
    $r('sys.color.ohos_id_color_titlebar_icon');
  }

  getMoreIconBgColor() {
    if (this.isMoreIconOnClick) {
      return $r('sys.color.ohos_id_color_click_effect');
    } else if (this.isMoreIconOnHover) {
      return $r('sys.color.ohos_id_color_hover');
    } else {
      return Color.Transparent;
    }
  }

  aboutToAppear() {
    try {
      let uiContent: UIContext = this.getUIContext();
      this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
      this.maxFontScale = uiContent.getMaxFontScale();
    } catch (err) {
      let code: number = (err as BusinessError)?.code;
      let message: string = (err as BusinessError)?.message;
      hilog.error(0x3900, 'ComposeTitleBar',
        `Failed to init fontsizescale info, cause, code: ${code}, message: ${message}`);
    }
    if (this.menuItems) {
      this.menuItems.forEach((item, index) => {
        if (item.isEnabled && this.firstFocusableIndex === -1 &&
          index > CollapsibleMenuSection.maxCountOfVisibleItems - 2) {
          this.firstFocusableIndex = this.index * 1000 + index + 1;
        }
      })
    }
    this.fontSize = this.decideFontScale()
  }

  decideFontScale(): number {
    try {
      let uiContent: UIContext = this.getUIContext();
      this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config?.fontSizeScale ?? 1;
      if (!this.isFollowingSystemFontScale) {
        return 1;
      }
      return Math.min(this.systemFontScale, this.maxFontScale);
    } catch (exception) {
      let code: number = (exception as BusinessError)?.code;
      let message: string = (exception as BusinessError)?.message;
      hilog.error(0x3900, 'ComposeTitleBar', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
      return 1;
    }
  }

  onFontSizeUpdated(): void {
    this.buttonGestureModifier.fontSize = this.fontSize;
  }

  build() {
    Column() {
      Row() {
        if (this.menuItems) {
          if (this.menuItems.length <= CollapsibleMenuSection.maxCountOfVisibleItems) {
            ForEach(this.menuItems, (item: ComposeTitleBarMenuItem, index: number) => {
              ImageMenuItem({ item: item, index: this.index * 1000 + index + 1, itemIndex: index })
            })
          } else {
            ForEach(this.menuItems.slice(0, CollapsibleMenuSection.maxCountOfVisibleItems - 1),
              (item: ComposeTitleBarMenuItem, index: number) => {
                ImageMenuItem({ item: item, index: this.index * 1000 + index + 1, itemIndex: index })
              })

            Button({ type: ButtonType.Normal, stateEffect: true }) {
              SymbolGlyph(PUBLIC_MORE)
                .fontSize(`${ImageMenuItem.imageSize}vp`)
                .fontColor([$r('sys.color.icon_primary')])
                .draggable(false)
                .focusable(true)
            }
            .accessibilityText($r('sys.string.ohos_toolbar_more'))
            .width(ImageMenuItem.imageHotZoneWidth)
            .height(ImageMenuItem.imageHotZoneWidth)
            .borderRadius(ImageMenuItem.buttonBorderRadius)
            .foregroundColor(this.getMoreIconFgColor())
            .backgroundColor(this.getMoreIconBgColor())
            .stateStyles({
              focused: {
                .border({
                  radius: $r('sys.float.ohos_id_corner_radius_clicked'),
                  width: ImageMenuItem.focusBorderWidth,
                  color: $r('sys.color.ohos_id_color_focused_outline'),
                  style: BorderStyle.Solid
                })
              },
              normal: {
                .border({
                  radius: $r('sys.float.ohos_id_corner_radius_clicked'),
                  width: 0
                })
              }
            })
            .onFocus(() => this.isMoreIconOnFocus = true)
            .onBlur(() => this.isMoreIconOnFocus = false)
            .onHover((isOn) => this.isMoreIconOnHover = isOn)
            .onKeyEvent((event) => {
              if (event.keyCode !== KeyCode.KEYCODE_ENTER &&
                event.keyCode !== KeyCode.KEYCODE_SPACE) {
                return;
              }
              if (event.type === KeyType.Down) {
                this.isMoreIconOnClick = true;
              }
              if (event.type === KeyType.Up) {
                this.isMoreIconOnClick = false;
              }
            })
            .onTouch((event) => {
              if (event.type === TouchType.Down) {
                this.isMoreIconOnClick = true;
              }
              if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
                this.isMoreIconOnClick = false;
                if (this.fontSize >= this.minFontSize) {
                  this.dialogController?.close();
                }
              }
            })
            .onClick(() => this.isPopupShown = true)
            .gestureModifier(this.buttonGestureModifier)
            .bindPopup(this.isPopupShown, {
              builder: this.popupBuilder,
              placement: Placement.Bottom,
              popupColor: Color.White,
              enableArrow: false,
              onStateChange: (e) => {
                this.isPopupShown = e.isVisible;
                if (!e.isVisible) {
                  this.isMoreIconOnClick = false;
                }
              }
            })
          }
        }
      }
    }
    .height('100%')
    .margin({ right: $r('sys.float.ohos_id_default_padding_end') })
    .justifyContent(FlexAlign.Center)
  }

  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Layoutable[], constraint: ConstraintSizeOptions): void {
    children.forEach((child) => {
      child.layout({ x: 0, y: 0 });
    })
    this.fontSize = this.decideFontScale();
  }

  @Builder
  popupBuilder() {
    Column() {
      if (this.menuItems) {
        ForEach(this.menuItems.slice(CollapsibleMenuSection.maxCountOfVisibleItems - 1,
          this.menuItems.length),
          (item: ComposeTitleBarMenuItem, index: number) => {
            ImageMenuItem({
              item: item, index: this.index * 1000 +
              CollapsibleMenuSection.maxCountOfVisibleItems + index, isPopup: false
            })
          })
      }
    }
    .width(ImageMenuItem.imageHotZoneWidth +
      CollapsibleMenuSection.focusPadding * CollapsibleMenuSection.marginsNum)
    .margin({ top: CollapsibleMenuSection.focusPadding, bottom: CollapsibleMenuSection.focusPadding })
    .onAppear(() => {
      focusControl.requestFocus(ImageMenuItem.focusablePrefix +
      this.firstFocusableIndex)
    })
  }
}

@Component
struct ImageMenuItem {
  item: ComposeTitleBarMenuItem = {} as ComposeTitleBarMenuItem;
  index: number = 0;
  itemIndex?: number = 0;
  minFontSize: number = 1.75;
  isFollowingSystemFontScale: boolean = false;
  maxFontScale: number = 1;
  systemFontScale?: number = 1;
  isPopup: boolean = true;
  static readonly imageSize = 24;
  static readonly imageHotZoneWidth = 48;
  static readonly buttonBorderRadius = 8;
  static readonly focusBorderWidth = 2;
  static readonly focusablePrefix = 'Id-ComposeTitleBar-ImageMenuItem-';
  @State isOnFocus: boolean = false;
  @State isOnHover: boolean = false;
  @State isOnClick: boolean = false;
  @Prop @Watch('onFontSizeUpdated') fontSize: number = 1;
  @Consume('uniqueId') parentParentUniqueId?: number;
  dialogController: CustomDialogController | null = new CustomDialogController({
    builder: ComposeTitleBarDialog({
      cancel: () => {
      },
      confirm: () => {
      },
      itemComposeTitleDialog: this.item,
      composeTitleBarDialog: this.item.label ? this.item.label : this.textDialog(),
      fontSize: this.fontSize,
    }),
    maskColor: Color.Transparent,
    isModal: true,
    customStyle: true,
  })

  @State buttonGestureModifier: ButtonGestureModifier = new ButtonGestureModifier(this.dialogController);

  private textDialog(): ResourceStr {
    if (this.item.value === PUBLIC_MORE) {
      return $r('sys.string.ohos_toolbar_more');
    } else if (this.item.value === PUBLIC_BACK) {
      return $r('sys.string.icon_back');
    } else {
      return this.item.label ? this.item.label : '';
    }
  }

  private toStringFormat(resource: ResourceStr | undefined): string | undefined {
    if (typeof resource === 'string') {
      return resource;
    } else if (typeof resource === 'undefined') {
      return '';
    } else {
      let resourceString: string = '';
      try {
        if (resource.id === -1 ) {
          resourceString = getContext()?.resourceManager?.getStringByNameSync(resource.params?.[0].split('.').pop());
        } else {
          resourceString = getContext()?.resourceManager?.getStringSync(resource);
        }
      } catch (err) {
        let code: number = (err as BusinessError)?.code;
        let message: string = (err as BusinessError)?.message;
        hilog.error(0x3900, 'Ace', `Faild to ComposeTitleBar toStringFormat,code: ${code},message:${message}`);
      }
      return resourceString;
    }
  }

  private getAccessibilityReadText(): string | undefined {
    if (this.item.value === PUBLIC_BACK) {
      try {
        return getContext()?.resourceManager?.getStringByNameSync('icon_back');
      } catch (err) {
        let code: number = (err as BusinessError)?.code;
        let message: string = (err as BusinessError)?.message;
        hilog.error(0x3900, 'Ace',
          `Faild to ComposeTitleBar getStringByNameSync icon_back,code: ${code},message:${message}`);
      }
    } else if (this.item.value === PUBLIC_MORE) {
      try {
        return getContext()?.resourceManager?.getStringByNameSync('ohos_toolbar_more');
      } catch (err) {
        let code: number = (err as BusinessError)?.code;
        let message: string = (err as BusinessError)?.message;
        hilog.error(0x3900, 'Ace',
          `Faild to ComposeTitleBar getStringByNameSync ohos_toolbar_more,code: ${code},message:${message}`);
      }
    } else if (this.item.accessibilityText) {
      return this.item.accessibilityText as string;
    } else if (this.item.label) {
      return this.item.label as string;
    }
    return ' ';
  }

  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Layoutable[], constraint: ConstraintSizeOptions): void {
    children.forEach((child) => {
      child.layout({ x: 0, y: 0 });
    })
    this.fontSize = this.decideFontScale();
  }


  getFgColor() {
    return this.isOnClick
      ? $r('sys.color.ohos_id_color_titlebar_icon_pressed')
      : $r('sys.color.ohos_id_color_titlebar_icon');
  }

  getBgColor() {
    if (this.isOnClick) {
      return $r('sys.color.ohos_id_color_click_effect');
    } else if (this.isOnHover) {
      return $r('sys.color.ohos_id_color_hover');
    } else {
      return Color.Transparent;
    }
  }

  aboutToAppear() {
    try {
      let uiContent: UIContext = this.getUIContext();
      this.isFollowingSystemFontScale = uiContent.isFollowingSystemFontScale();
      this.maxFontScale = uiContent.getMaxFontScale();
    } catch (err) {
      let code: number = (err as BusinessError)?.code;
      let message: string = (err as BusinessError)?.message;
      hilog.error(0x3900, 'ComposeTitleBar',
        `Failed to init fontsizescale info, cause, code: ${code}, message: ${message}`);
    }
    this.fontSize = this.decideFontScale();
  }

  onFontSizeUpdated(): void {
    this.buttonGestureModifier.fontSize = this.fontSize;
  }

  decideFontScale(): number {
    try {
      let uiContent: UIContext = this.getUIContext();
      this.systemFontScale = (uiContent.getHostContext() as common.UIAbilityContext)?.config?.fontSizeScale ?? 1;
      if (!this.isFollowingSystemFontScale) {
        return 1;
      }
      return Math.min(this.systemFontScale, this.maxFontScale);
    } catch (exception) {
      let code: number = (exception as BusinessError)?.code;
      let message: string = (exception as BusinessError)?.message;
      hilog.error(0x3900, 'ComposeTitleBar', `Faild to decideFontScale,cause, code: ${code}, message: ${message}`);
      return 1;
    }
  }

  build() {
    if (this.isPopup) {
      Button({ type: ButtonType.Normal, stateEffect: this.item.isEnabled }) {
        if (this.item?.symbolStyle) {
          SymbolGlyph()
            .fontColor([$r('sys.color.ohos_id_color_text_primary')])
            .attributeModifier(this.item?.symbolStyle)
            .fontSize(`${ImageMenuItem.imageSize}vp`)
            .effectStrategy(SymbolEffectStrategy.NONE)
            .symbolEffect(new SymbolEffect(), false)
            .draggable(false)
            .focusable(this.item?.isEnabled)
            .key(ImageMenuItem.focusablePrefix + this.index)
        } else {
          if (Util.isSymbolResource(this.item.value)) {
            SymbolGlyph(this.item.value as Resource)
              .fontSize(`${ImageMenuItem.imageSize}vp`)
              .fontColor([$r('sys.color.ohos_id_color_text_primary')])
              .draggable(false)
              .focusable(this.item?.isEnabled)
              .key(ImageMenuItem.focusablePrefix + this.index)
          } else {
            Image(this.item?.value)
              .matchTextDirection(this.item?.value === PUBLIC_BACK ? true : false)
              .width(ImageMenuItem.imageSize)
              .draggable(false)
              .height(ImageMenuItem.imageSize)
              .focusable(this.item?.isEnabled)
              .key(ImageMenuItem.focusablePrefix + this.index)
              .fillColor($r('sys.color.ohos_id_color_text_primary'))
          }
        }
      }
      .id(`ComposeTitleBar_ImageMenuItem_${this.parentParentUniqueId}_${this.itemIndex}`)
      .accessibilityText(this.getAccessibilityReadText())
      .accessibilityLevel(this.item?.accessibilityLevel ?? 'auto')
      .accessibilityDescription(this.item?.accessibilityDescription as string)
      .enabled(this.item.isEnabled ? this.item.isEnabled : false)
      .width(ImageMenuItem.imageHotZoneWidth)
      .height(ImageMenuItem.imageHotZoneWidth)
      .borderRadius(ImageMenuItem.buttonBorderRadius)
      .foregroundColor(this.getFgColor())
      .backgroundColor(this.getBgColor())
      .stateStyles({
        focused: {
          .border({
            radius: $r('sys.float.ohos_id_corner_radius_clicked'),
            width: ImageMenuItem.focusBorderWidth,
            color: $r('sys.color.ohos_id_color_focused_outline'),
            style: BorderStyle.Solid
          })
        },
        normal: {
          .border({
            radius: $r('sys.float.ohos_id_corner_radius_clicked'),
            width: 0
          })
        }
      })
      .onFocus(() => {
        if (!this.item?.isEnabled) {
          return;
        }
        this.isOnFocus = true;
      })
      .onBlur(() => this.isOnFocus = false)
      .onHover((isOn) => {
        if (!this.item?.isEnabled) {
          return;
        }
        this.isOnHover = isOn;
      })
      .onKeyEvent((event) => {
        if (!this.item?.isEnabled) {
          return;
        }
        if (event.keyCode !== KeyCode.KEYCODE_ENTER &&
          event.keyCode !== KeyCode.KEYCODE_SPACE) {
          return;
        }
        if (event.type === KeyType.Down) {
          this.isOnClick = true;
        }
        if (event.type === KeyType.Up) {
          this.isOnClick = false;
        }
      })
      .onTouch((event) => {
        if (!this.item?.isEnabled) {
          return;
        }
        if (event.type === TouchType.Down) {
          this.isOnClick = true;
        }
        if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
          this.isOnClick = false;
          if (this.fontSize >= this.minFontSize) {
            this.dialogController?.close();
          }
        }
      })
      .onClick(() => {
        if (this.item) {
          return this.item.isEnabled && this.item.action?.();
        }
      })
      .gestureModifier(this.buttonGestureModifier)
    } else {
      Button({ type: ButtonType.Normal, stateEffect: this.item.isEnabled }) {
        if (this.item?.symbolStyle) {
          SymbolGlyph()
            .fontColor([$r('sys.color.ohos_id_color_text_primary')])
            .attributeModifier(this.item?.symbolStyle)
            .fontSize(`${ImageMenuItem.imageSize}vp`)
            .effectStrategy(SymbolEffectStrategy.NONE)
            .symbolEffect(new SymbolEffect(), false)
            .draggable(false)
            .focusable(this.item?.isEnabled)
            .key(ImageMenuItem.focusablePrefix + this.index)
        } else {
          if (Util.isSymbolResource(this.item.value)) {
            SymbolGlyph(this.item.value as Resource)
              .fontSize(`${ImageMenuItem.imageSize}vp`)
              .fontColor([$r('sys.color.ohos_id_color_text_primary')])
              .draggable(false)
              .focusable(this.item?.isEnabled)
              .key(ImageMenuItem.focusablePrefix + this.index)
          } else {
            Image(this.item?.value)
              .matchTextDirection(this.item?.value === PUBLIC_BACK ? true : false)
              .width(ImageMenuItem.imageSize)
              .draggable(false)
              .height(ImageMenuItem.imageSize)
              .focusable(this.item?.isEnabled)
              .key(ImageMenuItem.focusablePrefix + this.index)
              .fillColor($r('sys.color.ohos_id_color_text_primary'))
          }
        }
      }
      .id(`ComposeTitleBar_ImageMenuItem_${this.parentParentUniqueId}_${this.itemIndex}`)
      .accessibilityText(this.getAccessibilityReadText())
      .accessibilityLevel(this.item?.accessibilityLevel ?? 'auto')
      .accessibilityDescription(this.item?.accessibilityDescription as string)
      .enabled(this.item.isEnabled ? this.item.isEnabled : false)
      .width(ImageMenuItem.imageHotZoneWidth)
      .height(ImageMenuItem.imageHotZoneWidth)
      .borderRadius(ImageMenuItem.buttonBorderRadius)
      .foregroundColor(this.getFgColor())
      .backgroundColor(this.getBgColor())
      .stateStyles({
        focused: {
          .border({
            radius: $r('sys.float.ohos_id_corner_radius_clicked'),
            width: ImageMenuItem.focusBorderWidth,
            color: $r('sys.color.ohos_id_color_focused_outline'),
            style: BorderStyle.Solid
          })
        },
        normal: {
          .border({
            radius: $r('sys.float.ohos_id_corner_radius_clicked'),
            width: 0
          })
        }
      })
      .onFocus(() => {
        if (!this.item?.isEnabled) {
          return;
        }
        this.isOnFocus = true;
      })
      .onBlur(() => this.isOnFocus = false)
      .onHover((isOn) => {
        if (!this.item?.isEnabled) {
          return;
        }
        this.isOnHover = isOn;
      })
      .onKeyEvent((event) => {
        if (!this.item?.isEnabled) {
          return;
        }
        if (event.keyCode !== KeyCode.KEYCODE_ENTER &&
          event.keyCode !== KeyCode.KEYCODE_SPACE) {
          return;
        }
        if (event.type === KeyType.Down) {
          this.isOnClick = true;
        }
        if (event.type === KeyType.Up) {
          this.isOnClick = false;
        }
      })
      .onTouch((event) => {
        if (!this.item?.isEnabled) {
          return;
        }
        if (event.type === TouchType.Down) {
          this.isOnClick = true;
        }
        if (event.type === TouchType.Up || event.type === TouchType.Cancel) {
          this.isOnClick = false;
          if (this.fontSize >= this.minFontSize) {
            this.dialogController?.close();
          }
        }
      })
      .onClick(() => {
        if (this.item) {
          return this.item.isEnabled && this.item.action?.();
        }
      })
    }

  }
}

/**
 *  ComposeTitleBarDialog
 */
@CustomDialog
struct ComposeTitleBarDialog {
  itemComposeTitleDialog: ComposeTitleBarMenuItem = {} as ComposeTitleBarMenuItem;
  callbackId: number | undefined = undefined;
  composeTitleBarDialog?: ResourceStr = '';
  mainWindowStage: window.Window | undefined = undefined;
  controller?: CustomDialogController;
  minFontSize: number = 1.75;
  maxFontSize: number = 3.2;
  screenWidth: number = 640;
  verticalScreenLines: number = 6;
  horizontalsScreenLines: number = 1;
  @StorageLink('mainWindow') mainWindow: Promise<window.Window> | undefined = undefined;
  @State fontSize: number = 1;
  @State maxLines: number = 1;
  @StorageProp('windowStandardHeight') windowStandardHeight: number = 0;
  cancel: () => void = () => {
  }
  confirm: () => void = () => {
  }

  build() {
    if (this.composeTitleBarDialog) {
      Column() {
        if (this.itemComposeTitleDialog.symbolStyle) {
          SymbolGlyph()
            .fontColor([$r('sys.color.icon_primary')])
            .attributeModifier(this.itemComposeTitleDialog.symbolStyle)
            .fontSize(IMAGE_SIZE)
            .effectStrategy(SymbolEffectStrategy.NONE)
            .symbolEffect(new SymbolEffect(), false)
            .margin({
              top: $r('sys.float.padding_level24'),
              bottom: $r('sys.float.padding_level8'),
            })
        } else {
          if (Util.isSymbolResource(this.itemComposeTitleDialog.value)) {
            SymbolGlyph(this.itemComposeTitleDialog.value as Resource)
              .fontSize(IMAGE_SIZE)
              .fontColor([$r('sys.color.icon_primary')])
              .margin({
                top: $r('sys.float.padding_level24'),
                bottom: $r('sys.float.padding_level8'),
              })
          } else {
            Image(this.itemComposeTitleDialog.value)
              .width(IMAGE_SIZE)
              .height(IMAGE_SIZE)
              .margin({
                top: $r('sys.float.padding_level24'),
                bottom: $r('sys.float.padding_level8'),
              })
              .fillColor($r('sys.color.icon_primary'))
          }
        }
        Column() {
          Text(this.composeTitleBarDialog)
            .fontSize(TEXT_EDITABLE_DIALOG)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
            .maxLines(this.maxLines)
            .width('100%')
            .textAlign(TextAlign.Center)
            .fontColor($r('sys.color.font_primary'))
        }
        .width('100%')
        .padding({
          left: $r('sys.float.padding_level4'),
          right: $r('sys.float.padding_level4'),
          bottom: $r('sys.float.padding_level12'),
        })
      }
      .width(this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG)
      .constraintSize({ minHeight: this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG })
      .backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK, undefined, { disableSystemAdaptation: true })
      .shadow(ShadowStyle.OUTER_DEFAULT_LG)
      .borderRadius($r('sys.float.corner_radius_level10'))
    } else {
      Column() {
        if (this.itemComposeTitleDialog.symbolStyle) {
          SymbolGlyph()
            .fontColor([$r('sys.color.icon_primary')])
            .attributeModifier(this.itemComposeTitleDialog.symbolStyle)
            .fontSize(IMAGE_SIZE)
            .effectStrategy(SymbolEffectStrategy.NONE)
            .symbolEffect(new SymbolEffect(), false)
        } else {
          if (Util.isSymbolResource(this.itemComposeTitleDialog.value)) {
            SymbolGlyph(this.itemComposeTitleDialog.value as Resource)
              .fontSize(IMAGE_SIZE)
              .fontColor([$r('sys.color.icon_primary')])
          } else {
            Image(this.itemComposeTitleDialog.value)
              .width(IMAGE_SIZE)
              .height(IMAGE_SIZE)
              .fillColor($r('sys.color.icon_primary'))
          }
        }
      }
      .width(this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG)
      .constraintSize({ minHeight: this.fontSize === this.maxFontSize ? MAX_DIALOG : MIN_DIALOG })
      .backgroundBlurStyle(BlurStyle.COMPONENT_ULTRA_THICK, undefined, { disableSystemAdaptation: true })
      .shadow(ShadowStyle.OUTER_DEFAULT_LG)
      .borderRadius($r('sys.float.corner_radius_level10'))
      .justifyContent(FlexAlign.Center)
    }
  }

  async aboutToAppear(): Promise<void> {
    try {
      let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
      this.mainWindowStage = context.windowStage.getMainWindowSync();
      let properties: window.WindowProperties = this.mainWindowStage.getWindowProperties();
      let rect = properties.windowRect;
      if (px2vp(rect.height) > this.screenWidth) {
        this.maxLines = this.verticalScreenLines;
      } else {
        this.maxLines = this.horizontalsScreenLines;
      }
    } catch (exception) {
      let code: number = (exception as BusinessError)?.code;
      let message: string = (exception as BusinessError)?.message;
      hilog.error(0x3900, 'ComposeTitleBar', `Faild to getMainWindowSync,cause, code: ${code}, message: ${message}`);
    }
  }
}

export { ComposeTitleBar }