import { ChangeDetectionStrategy, Component, OnInit, inject } from '@angular/core';
import {
  emailNotificationValidator,
  mobileNotificationValidator,
} from '@shared/components/notification-channel-control';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { combineLatest } from 'rxjs';
import { CheckoutReviewStore } from '../checkout-review.store';
import { first, map, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators';
import { ApplicationService } from '@core/application';
import { DomainCheckoutService } from '@domain/checkout';
import { Router } from '@angular/router';
import { BuyerDTO, NotificationChannel } from '@generated/swagger/checkout-api';
import { CustomerSearchNavigation } from '@shared/services/navigation';

@Component({
  selector: 'page-checkout-review-details',
  templateUrl: 'checkout-review-details.component.html',
  styleUrls: ['checkout-review-details.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: false,
})
export class CheckoutReviewDetailsComponent implements OnInit {
  customerNavigation = inject(CustomerSearchNavigation);

  control: UntypedFormGroup;

  customerFeatures$ = this._store.customerFeatures$;

  payer$ = this._store.payer$;
  buyer$ = this._store.buyer$;

  showNotificationChannels$ = combineLatest([this._store.shoppingCartItems$, this.payer$, this.buyer$]).pipe(
    takeUntil(this._store.orderCompleted),
    map(
      ([items, payer, buyer]) =>
        (!!payer || !!buyer) &&
        items.some((item) => item.features?.orderType === 'Rücklage' || item.features?.orderType === 'Abholung'),
    ),
  );

  notificationChannel$ = this._application.activatedProcessId$.pipe(
    takeUntil(this._store.orderCompleted),
    switchMap((processId) => this._domainCheckoutService.getNotificationChannels({ processId })),
  );

  communicationDetails$ = this._application.activatedProcessId$.pipe(
    takeUntil(this._store.orderCompleted),
    switchMap((processId) => this._domainCheckoutService.getBuyerCommunicationDetails({ processId })),
    map((communicationDetails) => communicationDetails ?? { email: undefined, mobile: undefined }),
  );

  specialComment$ = this._application.activatedProcessId$.pipe(
    switchMap((processId) => this._domainCheckoutService.getSpecialComment({ processId })),
  );

  shippingAddress$ = this._application.activatedProcessId$.pipe(
    takeUntil(this._store.orderCompleted),
    switchMap((processId) => this._domainCheckoutService.getShippingAddress({ processId })),
  );

  showAddresses$ = this._store.shoppingCartItems$.pipe(
    takeUntil(this._store.orderCompleted),
    withLatestFrom(this.customerFeatures$, this.payer$, this.shippingAddress$),
    map(([items, customerFeatures, payer, shippingAddress]) => {
      const hasShippingOrBillingAddresses = !!payer?.address || !!shippingAddress;
      const hasShippingFeature = items.some(
        (item) =>
          item.features?.orderType === 'Versand' ||
          item.features?.orderType === 'B2B-Versand' ||
          item.features?.orderType === 'DIG-Versand',
      );

      const isB2bCustomer = !!customerFeatures?.b2b;

      return hasShippingOrBillingAddresses && (hasShippingFeature || isB2bCustomer);
    }),
  );

  notificationChannelLoading$ = this._store.notificationChannelLoading$;

  constructor(
    private _fb: UntypedFormBuilder,
    private _store: CheckoutReviewStore,
    private _application: ApplicationService,
    private _domainCheckoutService: DomainCheckoutService,
    private _router: Router,
  ) {}

  async ngOnInit() {
    await this.initNotificationsControl();
  }

  async initNotificationsControl() {
    const fb = this._fb;
    const notificationChannel = await this.notificationChannel$.pipe(first()).toPromise();
    const communicationDetails = await this.communicationDetails$.pipe(first()).toPromise();

    let selectedNotificationChannel = 0;
    if ((notificationChannel & 1) === 1 && communicationDetails.email) {
      selectedNotificationChannel += 1;
    }
    if ((notificationChannel & 2) === 2 && communicationDetails.mobile) {
      selectedNotificationChannel += 2;
    }
    // #1967 Wenn E-Mail und SMS als NotificationChannel gesetzt sind, nur E-Mail anhaken
    if ((selectedNotificationChannel & 3) === 3) {
      selectedNotificationChannel = 1;
    }

    if (!this._store.notificationsControl) {
      this.control = fb.group({
        notificationChannel: new UntypedFormGroup({
          selected: new UntypedFormControl(selectedNotificationChannel),
          email: new UntypedFormControl(
            communicationDetails ? communicationDetails.email : '',
            emailNotificationValidator,
          ),
          mobile: new UntypedFormControl(
            communicationDetails ? communicationDetails.mobile : '',
            mobileNotificationValidator,
          ),
        }),
      });
      this._store.notificationsControl = this.control;
    } else {
      this.control = this._store.notificationsControl;
    }
  }

  setAgentComment(agentComment: string) {
    this._domainCheckoutService.setSpecialComment({ processId: this._application.activatedProcessId, agentComment });
  }

  updateNotifications(notificationChannels?: NotificationChannel[]) {
    this._store.onNotificationChange(notificationChannels);
  }

  getNameFromBuyer(buyer: BuyerDTO): { value: string; label: string } {
    if (buyer?.lastName && buyer?.firstName) {
      return { value: `${buyer?.lastName}, ${buyer?.firstName}`, label: 'Nachname, Vorname' };
    } else if (buyer?.lastName) {
      return { value: buyer?.lastName, label: 'Nachname, Vorname' };
    } else if (buyer?.firstName) {
      return { value: buyer?.firstName, label: 'Nachname, Vorname' };
    } else if (buyer?.organisation?.name) {
      return { value: buyer?.organisation?.name, label: 'Firmenname' };
    } else {
      return;
    }
  }

  async changeAddress() {
    const processId = this._application.activatedProcessId;
    const customer = await this._domainCheckoutService.getBuyer({ processId }).pipe(first()).toPromise();
    if (!customer) {
      this.navigateToCustomerSearch(processId);
      return;
    }
    const customerId = customer.source;
    await this.customerNavigation.navigateToDetails({
      processId,
      customerId,
      customer: { customerNumber: customer.buyerNumber },
    });
    // this._router.navigate(['/kunde', this._application.activatedProcessId, 'customer', 'search', `${customerId}`]);
  }

  async navigateToCustomerSearch(processId: number) {
    try {
      const response = await this.customerFeatures$
        .pipe(
          first(),
          switchMap((customerFeatures) => {
            return this._domainCheckoutService.canSetCustomer({ processId, customerFeatures });
          }),
        )
        .toPromise();

      this._router.navigate(['/kunde', this._application.activatedProcessId, 'customer', 'search'], {
        queryParams: { filter_customertype: response.filter.customertype },
      });
    } catch (error) {
      this._router.navigate(['/kunde', this._application.activatedProcessId, 'customer', 'search']);
    }
  }
}
