/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
 * 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 { settings } from '@kit.BasicServicesKit';
import lazy { AlertDialog } from '@ohos.arkui.advanced.Dialog';
import {
  FOCUS_BOX_PADDING_METRICS,
  PADDING_0,
  PADDING_12,
  PADDING_16,
  PADDING_2,
  PADDING_4,
  PADDING_8
} from '@ohos/settings.common/src/main/ets/constant/StyleConstant';
import { EventBus } from '@ohos/settings.common/src/main/ets/framework/common/EventBus';
import { PageRouter } from '@ohos/settings.common/src/main/ets/framework/common/PageRouter';
import { SettingBaseModel } from '@ohos/settings.common/src/main/ets/framework/model/SettingBaseModel';
import { SettingItemModel } from '@ohos/settings.common/src/main/ets/framework/model/SettingItemModel';
import { CompStateEvent, SettingCompState } from '@ohos/settings.common/src/main/ets/framework/model/SettingStateModel';
import { DisplayUtils } from '@ohos/settings.common/src/main/ets/utils/DisplayUtils';
import { NavEntryKey } from '@ohos/settings.common/src/main/ets/utils/Consts';
import {
  DeviceNameUtil,
  CHECK_SUCCESS,
  CHECK_FAIL_REASON_NETWORK,
  CHECK_FAIL_REASON_LOG_IN,
  ABOUT_DEVICE_NAME_COMP_ID
} from '@ohos/settings.common/src/main/ets/utils/DeviceNameUtils';
import { FontScaleUtils } from '@ohos/settings.common/src/main/ets/utils/FontScaleUtils';
import { LogUtil } from '@ohos/settings.common/src/main/ets/utils/LogUtil';
import { PreferencesUtil } from '@ohos/settings.common/src/main/ets/utils/PreferencesUtil';
import { ResourceUtil } from '@ohos/settings.common/src/main/ets/utils/ResourceUtil';
import { SettingsDataUtils } from '@ohos/settings.common/src/main/ets/utils/SettingsDataUtils';
import { ToastUtil } from '@ohos/settings.common/src/main/ets/utils/ToastUtil';
import { CommonDialog } from '@ohos/settings.uikit/src/main/ets/dialog/CommonDialog';
import { DialogButtonType } from '@ohos/settings.uikit/src/main/ets/dialog/types';
import { DeviceNameController, SHOW_DEVICE_NAME_SHEET } from '../controller/DeviceNameController';
import { NameUpdateSheetComponent } from './NameUpdateSheetComponent';
import common from '@ohos.bluetooth.common';

const OPACITY_PERCENT_FULL: number = 1;
const MAX_LENGTH: number = 30;
const SETTINGS_DATA_DISPLAY_DEVICE_NAME: string = 'settings.general.display_device_name';
const ALPHA_DISABLED: Resource = $r('sys.float.alpha_tertiary');
const DEVICE_NAME_SETTINGS: string = 'DeviceNameSettings';

@Component
export struct DeviceNameItemComponent {
  tag: string = 'DeviceNameItemComponent: ';
  item?: SettingItemModel;
  controller?: DeviceNameController;
  hint?: ResourceStr;
  maxLength: number = MAX_LENGTH;
  blueToothName: boolean = false;
  private logInDialogController: CustomDialogController | undefined = undefined;
  private compStateEvent?: CompStateEvent;
  @State textValue: ResourceStr = '';
  @State inputValue: ResourceStr = '';
  @State isShow: boolean = false;
  @State sheetHeight: number = 300;
  @State title: ResourceStr = '';
  @State isToggleEnable: boolean = true;
  @State isGrayed: boolean = PreferencesUtil.getSync(DEVICE_NAME_SETTINGS, false) as boolean;
  @State isEnable: boolean = true;
  @State isHover: boolean = false;

  private isExtraLargeFontMode() {
    return FontScaleUtils.isExtraLargeFontMode();
  }

  build() {
    Flex({ wrap: this.isExtraLargeFontMode() ? FlexWrap.Wrap : FlexWrap.NoWrap,
      justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
      Row() {
        Text($r('app.string.device_name_settings_title'))
          .fontColor($r('sys.color.font_primary'))
          .fontSize($r('sys.float.Body_L'))
          .fontWeight(FontWeight.Medium)
          .align(Alignment.Center)
          .fontFamily('HarmonyHeiTi')
          .constraintSize({
            minHeight: 21,
          })
      }
      .flexGrow(0)
      .flexShrink(0)
      .align(Alignment.Start)

      Flex({ justifyContent: FlexAlign.End, alignItems: ItemAlign.Center }) {
        Column() {
          Text(this.title)
            .fontColor($r('sys.color.font_secondary'))
            .fontSize($r('sys.float.Body_M'))
            .fontFamily('HarmonyHeiTi')
            .fontWeight(FontWeight.Regular)
            .constraintSize({
              minHeight: 19,
            })
            .wordBreak(WordBreak.BREAK_WORD)
        }
        .margin({
          start: PADDING_2,
          end: PADDING_2,
        })
        .flexGrow(1)
        .alignItems(this.isExtraLargeFontMode() ? HorizontalAlign.Start : HorizontalAlign.End)
        .justifyContent(FlexAlign.Center)

        if (this.blueToothName === false) {
          SymbolGlyph($r('sys.symbol.chevron_right'))
            .fontColor([$r('sys.color.icon_fourth')])
            .draggable(false)
            .fontSize('24vp')
            .margin({
              start: PADDING_4,
            })
        }
      }
      .padding({
        start: this.isExtraLargeFontMode() ? PADDING_0 : PADDING_16,
      })
    }
    .focusBox({ margin: FOCUS_BOX_PADDING_METRICS })
    .enabled(this.isEnable)
    .opacity(this.isEnable ? OPACITY_PERCENT_FULL : ALPHA_DISABLED)
    .width('100%')
    .padding({
      start: PADDING_8,
      end: PADDING_8,
      top: this.isExtraLargeFontMode() ? FontScaleUtils.getSafetyPadding() : PADDING_12,
      bottom: this.isExtraLargeFontMode() ? FontScaleUtils.getSafetyPadding() : PADDING_12,
    })
    .borderRadius($r('sys.float.corner_radius_level8'))
    .stateStyles({
      normal: this.normalStyles,
      pressed: this.pressedStyles,
    })
    .onClick(() => {
      if (this.blueToothName) {
        return
      }
      this.controller?.checkUpdateCondition().then((result) => {
        /* instrument ignore if*/
        if (result !== CHECK_SUCCESS) {
          LogUtil.info(`update device name pre check fail, result: ${result}`);
          this.handlePreCheckFail(result);
          return;
        }
        this.isShow = true;
        LogUtil.info(`onclick show sheet, isShow: ${this.isShow}`);
      });
    })
    .onHover((hover: boolean) => {
      this.isHover = hover;
    })
    .bindSheet(this.isShow, this.controller?.sheetBuilder ? this.customSheetBuilder() : this.updateNameSheetBuilder(), {
      detents: [DisplayUtils.getScreenHeight() * 0.75],
      height: 320,
      preferType: SheetType.CENTER,
      dragBar: true,
      title: { title: $r('app.string.change_device_name') },
      backgroundColor: $r('sys.color.ohos_id_color_dialog_bg'),
      maskColor: $r('sys.color.mask_fourth'),
      showClose: true,
      keyboardAvoidMode: SheetKeyboardAvoidMode.RESIZE_ONLY,
      onDisappear: () => {
        this.controller?.onSheetDisappear();
      },
      onWillDisappear: () => {
        LogUtil.info(`${this.tag} onWillDisappear`);
        this.isShow = false;
      },
    })
  }

  @Builder
  customSheetBuilder() {
    this.controller?.sheetBuilder?.builder.builder(this.controller?.sheetBuilder?.param)
  }

  @Builder
  updateNameSheetBuilder() {
    Column() {
      NameUpdateSheetComponent({
        textValue: this.textValue,
        inputValue: this.inputValue,
        hint: this.hint,
        maxLength: this.maxLength,
        primaryButton: $r('app.string.dialog_sure'),
        needReConfirm: this.controller?.needReConfirm,
        confirm: () => {
          LogUtil.info(`${this.tag} confirm`);
          this.controller?.onPrimaryButtonClick(getContext(this), this.inputValue.toString());
        },
        reConfirm: () => {
          /* instrument ignore if*/
          if (this.controller?.needReConfirm) {
            let res: boolean = this.controller.updateConfirm(this.inputValue.toString());
            if (res) {
              let reConfirmDialogController = new CustomDialogController({
                builder: CommonDialog({
                  title: ResourceUtil.getStringSync($r('app.string.attention')),
                  actionType: DialogButtonType.TWO_BUTTON_HORIZONTAL,
                  cancelText: $r('app.string.cancel'),
                  cancelCallback: () => {
                    reConfirmDialogController.close();
                  },
                  confirmText: $r('app.string.modify'),
                  confirmCallback: () => {
                    EventBus.getInstance().emit('updateDeviceNameConfirm');
                    reConfirmDialogController.close();
                  },
                  content: () => {
                    this.buildReConfirmDialogContent();
                  },
                }),
              });
              reConfirmDialogController.open();
            }
          }
        },
        closeDialog: () => {
          LogUtil.info(`${this.tag} close sheet`);
          this.isShow = false;
        },
      })
    }
    .enabled(!this.isGrayed)
    .opacity(!this.isGrayed ? OPACITY_PERCENT_FULL : ALPHA_DISABLED)
  }

  @Styles
  normalStyles() {
    .backgroundColor(this.getNormalColor())
  }

  private getNormalColor(): ResourceColor {
    if (this.isHover) {
      return $r('sys.color.ohos_id_color_hover');
    }
    return Color.Transparent;
  }

  @Builder
  buildReConfirmDialogContent() {
    Column() {
      Text($r('app.string.confirm_change_name'))
        .fontFamily('HarmonyHeiTi')
        .fontWeight(FontWeight.Regular)
        .fontSize($r('sys.float.Body_L'))
        .fontColor($r('sys.color.font_primary'))
        .lineHeight(21)
    }
  }

  @Styles
  pressedStyles() {
    .backgroundColor($r('sys.color.interactive_click'))
  }

  aboutToAppear(): void {
    this.registerDataChange();
    this.initParam();
    this.controller?.init();
    LogUtil.info(`${this.tag} aboutToAppear`+JSON.stringify(this.item));
    this.isEnable = (this.item as SettingBaseModel).enabled ?? true;
    this.compStateEvent = new CompStateEvent(ABOUT_DEVICE_NAME_COMP_ID, {
      enabled: (enabledState: SettingCompState): void => {
        /* instrument ignore if*/
        if (enabledState.state !== undefined && enabledState.state !== this.isEnable) {
          this.isEnable = enabledState.state;
          this.isGrayed = !enabledState.state;
        }
      }
    });
    this.compStateEvent.on();
    EventBus.getInstance().on(SHOW_DEVICE_NAME_SHEET, (isShow: boolean) => {
      this.isShow = isShow;
    });
    if (this.controller) {
      this.controller.reConfirmCallBack = (result: boolean) => {
        LogUtil.info(`${this.tag} reConfirmCallBack result: ${result}`);
        EventBus.getInstance().emit('deviceNameCheck');
        if (result) {
          this.refreshData();
          this.isShow = false;
        }
      };
    }
  }

  private registerDataChange(): void {
    SettingsDataUtils.registerKeyObserverWithDomain(SETTINGS_DATA_DISPLAY_DEVICE_NAME,
      settings.domainName.USER_SECURITY,
      () => {
        LogUtil.info(`${this.tag} displayDeviceName data change`);
        this.title = DeviceNameUtil.getDisplayDeviceName();
        this.textValue = this.title;
        this.inputValue = this.title;
      })
  }

  private unRegisterDataChange(): void {
    SettingsDataUtils.unregisterKeyObserverWithDomain(SETTINGS_DATA_DISPLAY_DEVICE_NAME,
      settings.domainName.USER_SECURITY);
  }

  private initParam(): void {
    this.controller = this.item?.compControl as DeviceNameController;
    this.refreshData();
  }
//设备名称
  private refreshData(): void {
    this.title = this.controller?.result ?? '';
    this.textValue = this.controller?.textValue ?? '';
    this.inputValue = this.controller?.textValue ?? '';
  }

  aboutToDisappear(): void {
    this.unRegisterDataChange();
    this.controller?.destroy();
    LogUtil.info(`${this.tag} aboutToDisappear`);
    EventBus.getInstance().off(SHOW_DEVICE_NAME_SHEET);
    this.compStateEvent?.detach();
  }
  private handlePreCheckFail(reason: number): void {
    switch (reason) {
      case CHECK_FAIL_REASON_NETWORK:
        ToastUtil.showToast(ResourceUtil.getStringSync($r('app.string.network_tips')));
        break;
      case CHECK_FAIL_REASON_LOG_IN:
        // this.openLogInDialog();
        break;
      default:
        break;
    }
  }

}