// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { CommonModule } from "@angular/common";
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
import { takeUntilDestroyed, toSignal } from "@angular/core/rxjs-interop";
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
import { firstValueFrom, switchMap } from "rxjs";

import { JslibModule } from "@bitwarden/angular/jslib.module";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { BadgeSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/badge-settings.service";
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { AnimationControlService } from "@bitwarden/common/platform/abstractions/animation-control.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { Theme, ThemeTypes } from "@bitwarden/common/platform/enums";
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
import {
  CardComponent,
  CheckboxModule,
  FormFieldModule,
  Option,
  SelectModule,
} from "@bitwarden/components";
import {
  PermitCipherDetailsPopoverComponent,
  VaultCopyButtonsService,
  ShowQuickCopyActionsDetailsPopoverComponent,
} from "@bitwarden/vault";

import { PopupWidthOption } from "../../../platform/browser/browser-popup-utils";
import { PopOutComponent } from "../../../platform/popup/components/pop-out.component";
import { PopupCompactModeService } from "../../../platform/popup/layout/popup-compact-mode.service";
import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component";
import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component";
import { PopupSizeService } from "../../../platform/popup/layout/popup-size.service";

// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
  templateUrl: "./appearance.component.html",
  imports: [
    CommonModule,
    JslibModule,
    PopupPageComponent,
    PopupHeaderComponent,
    PopOutComponent,
    CardComponent,
    FormFieldModule,
    SelectModule,
    ReactiveFormsModule,
    CheckboxModule,
    PermitCipherDetailsPopoverComponent,
    ShowQuickCopyActionsDetailsPopoverComponent,
  ],
})
export class AppearanceComponent implements OnInit {
  private compactModeService = inject(PopupCompactModeService);
  private copyButtonsService = inject(VaultCopyButtonsService);
  private popupSizeService = inject(PopupSizeService);
  private i18nService = inject(I18nService);
  private configService = inject(ConfigService);
  private accountService = inject(AccountService);
  private billingAccountProfileService = inject(BillingAccountProfileStateService);

  /** Signal for the feature flag that controls simplified item action behavior */
  protected readonly simplifiedItemActionEnabled = toSignal(
    this.configService.getFeatureFlag$(FeatureFlag.PM31039ItemActionInExtension),
    { initialValue: false },
  );

  protected readonly isPremiumUser = toSignal(
    this.accountService.activeAccount$.pipe(
      getUserId,
      switchMap((userId) => this.billingAccountProfileService.hasPremiumFromAnySource$(userId)),
    ),
  );

  appearanceForm = this.formBuilder.group({
    enableFavicon: false,
    enableBadgeCounter: true,
    theme: ThemeTypes.System as Theme,
    enableAnimations: true,
    enableCompactMode: false,
    showQuickCopyActions: false,
    width: "default" as PopupWidthOption,
    clickItemsToAutofillVaultView: false,
    showAtRiskNotifications: true,
  });

  /** To avoid flashes of inaccurate values, only show the form after the entire form is populated. */
  formLoading = true;

  /** Available theme options */
  themeOptions: { name: string; value: Theme }[];

  /** Available width options */
  protected readonly widthOptions: Option<PopupWidthOption>[] = [
    { label: this.i18nService.t("default"), value: "default" },
    { label: this.i18nService.t("wide"), value: "wide" },
    { label: this.i18nService.t("narrow"), value: "narrow" },
  ];

  constructor(
    private messagingService: MessagingService,
    private domainSettingsService: DomainSettingsService,
    private badgeSettingsService: BadgeSettingsServiceAbstraction,
    private themeStateService: ThemeStateService,
    private formBuilder: FormBuilder,
    private destroyRef: DestroyRef,
    private animationControlService: AnimationControlService,
    i18nService: I18nService,
    private vaultSettingsService: VaultSettingsService,
  ) {
    this.themeOptions = [
      { name: i18nService.t("systemDefault"), value: ThemeTypes.System },
      { name: i18nService.t("light"), value: ThemeTypes.Light },
      { name: i18nService.t("dark"), value: ThemeTypes.Dark },
    ];
  }

  async ngOnInit() {
    const enableFavicon = await firstValueFrom(this.domainSettingsService.showFavicons$);
    const enableBadgeCounter = await firstValueFrom(this.badgeSettingsService.enableBadgeCounter$);
    const theme = await firstValueFrom(this.themeStateService.selectedTheme$);
    const enableAnimations = await firstValueFrom(
      this.animationControlService.enableRoutingAnimation$,
    );
    const enableCompactMode = await firstValueFrom(this.compactModeService.enabled$);
    const showQuickCopyActions = await firstValueFrom(
      this.copyButtonsService.showQuickCopyActions$,
    );
    const width = await firstValueFrom(this.popupSizeService.width$);
    const clickItemsToAutofillVaultView = await firstValueFrom(
      this.vaultSettingsService.clickItemsToAutofillVaultView$,
    );
    const showAtRiskNotifications = await firstValueFrom(
      this.vaultSettingsService.showAtRiskPasswordNotifications$,
    );

    // Set initial values for the form
    this.appearanceForm.setValue({
      enableFavicon,
      enableBadgeCounter,
      theme,
      enableAnimations,
      enableCompactMode,
      showQuickCopyActions,
      width,
      clickItemsToAutofillVaultView,
      showAtRiskNotifications,
    });

    this.formLoading = false;

    this.appearanceForm.controls.theme.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((newTheme) => {
        void this.saveTheme(newTheme);
      });

    this.appearanceForm.controls.enableFavicon.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((enableFavicon) => {
        void this.updateFavicon(enableFavicon);
      });

    this.appearanceForm.controls.enableBadgeCounter.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((enableBadgeCounter) => {
        void this.updateBadgeCounter(enableBadgeCounter);
      });

    this.appearanceForm.controls.enableAnimations.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((enableBadgeCounter) => {
        void this.updateAnimations(enableBadgeCounter);
      });

    this.appearanceForm.controls.enableCompactMode.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((enableCompactMode) => {
        void this.updateCompactMode(enableCompactMode);
      });

    this.appearanceForm.controls.showQuickCopyActions.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((showQuickCopyActions) => {
        void this.updateQuickCopyActions(showQuickCopyActions);
      });

    this.appearanceForm.controls.width.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((width) => {
        void this.updateWidth(width);
      });

    this.appearanceForm.controls.clickItemsToAutofillVaultView.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((clickItemsToAutofillVaultView) => {
        void this.updateClickItemsToAutofillVaultView(clickItemsToAutofillVaultView);
      });

    this.appearanceForm.controls.showAtRiskNotifications.valueChanges
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((showAtRiskNotifications) => {
        void this.updateShowAtRiskNotifications(showAtRiskNotifications);
      });
  }

  async updateClickItemsToAutofillVaultView(clickItemsToAutofillVaultView: boolean) {
    await this.vaultSettingsService.setClickItemsToAutofillVaultView(clickItemsToAutofillVaultView);
  }

  async updateShowAtRiskNotifications(showAtRiskNotifications: boolean) {
    await this.vaultSettingsService.setShowAtRiskPasswordNotifications(showAtRiskNotifications);
  }

  async updateFavicon(enableFavicon: boolean) {
    await this.domainSettingsService.setShowFavicons(enableFavicon);
  }

  async updateBadgeCounter(enableBadgeCounter: boolean) {
    await this.badgeSettingsService.setEnableBadgeCounter(enableBadgeCounter);
    this.messagingService.send("bgUpdateContextMenu");
  }

  async saveTheme(newTheme: Theme) {
    await this.themeStateService.setSelectedTheme(newTheme);
  }

  async updateAnimations(enableAnimations: boolean) {
    await this.animationControlService.setEnableRoutingAnimation(enableAnimations);
  }

  async updateCompactMode(enableCompactMode: boolean) {
    await this.compactModeService.setEnabled(enableCompactMode);
  }

  async updateQuickCopyActions(showQuickCopyActions: boolean) {
    await this.copyButtonsService.setShowQuickCopyActions(showQuickCopyActions);
  }

  async updateWidth(width: PopupWidthOption) {
    await this.popupSizeService.setWidth(width);
  }
}
