import { Component, OnInit, Optional } from '@angular/core';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { IBaseFleioObjectModel } from '@fleio-api/base-model/base-fleio-object.model';
import { IPluginComponent } from '@shared/plugins/interfaces/plugin-component';
import { ISelectDomainOrderOptionsModel } from '@fleio-api/plugins/domains/model/select-domain-order-options.model';
import { DomainRootApiService } from '@fleio-api/plugins/domains/domain-root-api.service';
import { UntypedFormBuilder } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import {
  SelectedExistingDomainService
} from './selected-existing-domain.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { PanelLayoutComponent } from '@shared/layout/panel-layout/panel-layout.component';
import { ConfigService } from '@shared/config/config.service';

@Component({
  selector: 'app-domains-select-domain',
  templateUrl: './domains-select-domain.component.html',
  styleUrls: ['./domains-select-domain.component.scss']
})
export class DomainsSelectDomainComponent extends DetailsFormBase<IBaseFleioObjectModel> implements OnInit, IPluginComponent {
  public data: Record<string, unknown>;
  public selectExistingDomainDataCart: {
    existing_domains: [];
  } = {
    existing_domains: [],
  };
  selectDomainForm = this.formBuilder.group({
    domain_operation: [''],
    selected_domain_name: [''],
    use_my_domain_option: [''],
  });
  selectedDomainName = this.selectDomainForm.controls.selected_domain_name;
  domainNameOk: boolean;
  public selectDomainOptions: ISelectDomainOrderOptionsModel;
  domainOperation = this.selectDomainForm.controls.domain_operation;
  useMyDomainOption = this.selectDomainForm.controls.use_my_domain_option;
  domainChecked: boolean;
  shouldLookup: boolean;
  pricePerYear;
  currency: string;
  hasErrors: boolean;
  errorText: string;
  hasTld: boolean;
  lookupMethod: string;
  loading: boolean;

  constructor(
    private domainRootApiService: DomainRootApiService,
    private formBuilder: UntypedFormBuilder,
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private selectedExistingDomainService: SelectedExistingDomainService,
    private notificationService: NotificationService,
    public config: ConfigService,
    @Optional() public panelLayout?: PanelLayoutComponent
  ) {
    super();
  }

  ngOnInit(): void {
    this.domainRootApiService.getSelectDomainOptions({}).subscribe(response => {
      this.selectDomainOptions = response;
      if (response?.domains_in_cart) {
        this.selectExistingDomainDataCart.existing_domains = response.domains_in_cart;
      } else {
        this.selectExistingDomainDataCart.existing_domains = [];
      }
    });

    this.selectedExistingDomainService.selectedExistingDomain.subscribe(value => {
      this.selectedDomainName.setValue(value);
    });

    this.selectDomainForm.controls.domain_operation.valueChanges.subscribe(value => {
      this.domainChecked = false;
      this.shouldLookup = false;
      this.hasErrors = false;
      if (this.selectedDomainName) {
        this.selectedDomainName.setValue('');
        this.selectedDomainName.valueChanges.subscribe(domainName => {
          this.hasErrors = false;
          this.domainNameOk = false;
          this.pricePerYear = null;
          this.currency = null;
        });
      }
    });

    this.useMyDomainOption.valueChanges.subscribe(value => {
      this.hasErrors = false;
      this.domainNameOk = false;
    });
  }

  newDomainSelected() {
    return (
      this.domainOperation.value === 'order_new' ||
      this.domainOperation.value === 'use_my_domain'
    );
  };

  shouldCheckDomain() {
    if (this.newDomainSelected()) {
      return !this.domainNameOk;
    } else {
      return false;
    }
  };

  canSubmit() {
    if (this.newDomainSelected()) {
      if (this.domainChecked) {
        return this.domainNameOk;
      } else {
        return !!this.selectedDomainName.value;
      }
    } else {
      return !!this.selectedDomainName.value;
    }
  }

  formSubmit() {
    if (this.canSubmit()) {
      if (this.shouldCheckDomain()) {
        this.hasTld = this.selectedDomainName.value.includes('.');

        if (!this.hasTld) {
          if (!this.selectDomainOptions.default_tld) {
            this.notificationService.showMessage($localize`No TLD specified and default TLD is not set.`);
            return;
          }
          const newDomainName = this.selectedDomainName.value + this.selectDomainOptions.default_tld;
          this.selectedDomainName.setValue(newDomainName);
        }

        if (this.domainOperation.value === 'order_new') {
          this.lookupMethod = 'is_available_for_registration';
        }

        if (this.domainOperation.value === 'use_my_domain' && this.useMyDomainOption.value === 'transfer') {
          this.lookupMethod = 'is_available_for_transfer';
        }

        this.loading = true;

        if (this.domainOperation.value === 'use_my_domain' && this.useMyDomainOption.value === 'use_external') {
          this.lookupMethod = 'is_available_for_registration';
          this.domainRootApiService.lookup(
            this.lookupMethod,
            this.selectedDomainName.value,
            // do not skip whois check from staff when using external domain
            this.config.authService.feature('ui.staff') ? false : null,
          ).subscribe({
            next: response => {
              if (response.in_db) {
                this.domainNameOk = false;
                this.hasErrors = true;
                this.errorText = response.error;
                this.loading = false;
              }
              else if (response.available) {
                this.domainNameOk = false;
                this.hasErrors = true;
                this.errorText = $localize`Domain is unregistered`;
                this.loading = false;
              } else {
                this.goToConfigureProduct();
              }
            }, error: error => {
              this.loading = false;
            }
          });
        } else {
          this.domainRootApiService.lookup(
            this.lookupMethod,
            this.selectedDomainName.value,
          ).subscribe(response => {
            if (response.available) {
              this.domainNameOk = true;
              this.pricePerYear = response.prices.prices_per_years[0];
              this.currency = response.prices.currency.code;
            } else {
              this.errorText = response.error;
              this.hasErrors = true;
            }
          }).add(() => {
            this.loading = false;
          });
        }
      } else {
        this.loading = true;
        this.goToConfigureProduct();
      }
    }
  }

  goToConfigureProduct() {
    let domainAction;
    if (this.domainOperation.value === 'order_new') {
      domainAction = this.domainOperation.value;
    } else {
      domainAction = this.useMyDomainOption.value;
    }
    if (this.config.authService.feature('ui.staff')) {
      this.router.navigateByUrl(
        this.config.getPanelUrl(`orders/order-product/${this.activatedRoute.snapshot.params.code}/${domainAction}/${this.selectedDomainName.value}`)
      );
    } else {
      this.router.navigate(
        [`billing/order/order-product/${this.activatedRoute.snapshot.params.code}/${domainAction}/${this.selectedDomainName.value}`]
      ).then(() => {
      });
    }
  };

}
