import { Component, OnDestroy } from '@angular/core';
import { DetailsComponentBase } from '@objects-view/details-component-base';
import { IBaseFleioObjectModel } from '@fleio-api/base-model/base-fleio-object.model';
import { FleioObjectsList } from '@fleio-api/fleio-objects-list';
import { CurrenciesApiService } from '@fleio-api/core/currencies-api.service';
import { ICurrencyModel } from '@fleio-api/billing/model/currency.model';
import { CallbackAction } from '@objects-view/actions/callback-action';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { Observable, of } from 'rxjs';
import { IAction } from '@objects-view/interfaces/actions/action';
import { map } from 'rxjs/operators';
import { MatDialog } from '@angular/material/dialog';
import { EditCurrencyDialogComponent } from './dialogs/edit-currency-dialog/edit-currency-dialog.component';
import { ICurrencyCreateOptions } from '@fleio-api/billing/model/currency-create-options';
import { NotificationService } from '@shared/ui-api/notification.service';
import { IPermissionsModel } from '@fleio-api/base-model/IPermissionsModel';
import { IIcon } from '@shared/ui/common/interfaces/icon';

@Component({
  selector: 'app-currencies',
  templateUrl: './currencies.component.html',
  styleUrls: ['./currencies.component.scss']
})
export class CurrenciesComponent
  extends DetailsComponentBase<IBaseFleioObjectModel> implements OnDestroy {

  public loadingCurrencies: boolean;
  public currencies: FleioObjectsList<ICurrencyModel>;
  public currencyActions: { [code: string]: IAction[] };
  private createOptions: ICurrencyCreateOptions;
  defaultCurrency: ICurrencyModel;

  defaultCurrencyInfo = {
    name: 'info',
    verticalAlign: 'middle',
    fontSize: '20px',
    marginLeft: '5px',
    marginTop: '2px',
    tooltip: $localize`The default currency is set on new client sign-up and is used for limits defined in Configurations.`,
  } as IIcon;

  constructor(
    private currenciesApiService: CurrenciesApiService, private matDialog: MatDialog,
    private notificationService: NotificationService,
  ) {
    super();
  }

  protected initTabData() {
    this.loadingCurrencies = true;
    this.currenciesApiService.list().subscribe((currencyList) => {
      this.currencies = currencyList;
      this.currencyActions = {};
      this.currencies.objects.forEach(currency => {
        this.currencyActions[currency.code] = this.getCurrencyActions(currency, this.currencies.permissions);
        if (currency.is_default) {
          this.defaultCurrency = currency;
        }
      });
      this.loadingCurrencies = false;
    });
    this.currenciesApiService.createOptions({}).subscribe(createOptions => {
      this.createOptions = createOptions as ICurrencyCreateOptions;
    });
  }

  createCurrency() {
    return this.matDialog.open(
      EditCurrencyDialogComponent, {
        data: {
          currency: null,
          defaultCurrency: this.defaultCurrency,
          createOptions: this.createOptions,
        },
        autoFocus: false,
      }).afterClosed().subscribe((value) => {
        if (value) {
          this.initTabData();
        }
    });
  }

  updateExchangeRates() {
    this.notificationService.confirmDialog(
      {
        title: $localize`Update exchange rates`,
        message: $localize`Do you want to update exchange rates?`
      }
    ).subscribe(result => {
      if (result?.button === 'yes') {
        this.currenciesApiService.updateExchangeRates().subscribe(() => {
          this.initTabData();
          this.notificationService.showMessage($localize`Exchange rates updated`);
        });
      }
    });
  }

  updateRelativePrices() {
    this.notificationService.confirmDialog(
      {
        title: $localize`Update relative prices`,
        message: $localize`Do you want to update relative prices?`
      }
    ).subscribe(result => {
      if (result?.button === 'yes') {
        this.currenciesApiService.updateRelativePrices().subscribe(() => {
          this.initTabData();
          this.notificationService.showMessage($localize`Relative prices updated.`);
        });
      }
    });
  }

  editCurrency(action: CallbackAction): Observable<IActionResult> {
    return this.matDialog.open(
      EditCurrencyDialogComponent, {
        data: {
          currency: action.object,
          defaultCurrency: this.defaultCurrency,
          createOptions: this.createOptions,
        },
        autoFocus: false,
      }).afterClosed().pipe(map((value) => {
        if (value) {
          this.initTabData();
          return {message: $localize`Currency updated`};
        }
      }
    ));
  }

  deleteCurrency(action: CallbackAction): Observable<IActionResult> {
    const currency = action.object as ICurrencyModel;
    this.currenciesApiService.delete(currency.code).subscribe(response => {
      this.initTabData();
    }, error => {
      if (error && error.error && error.error.detail) {
        if (error.error.error_type === 'ProtectedError') {
          this.notificationService.showMessage(error.error.user_friendly_message);
        } else {
          this.notificationService.showMessage(error.error.detail);
        }
      }
    });
    return of(null);
  }

  getCurrencyActions(currency: ICurrencyModel, permissions: IPermissionsModel): IAction[] {
    const actions = [
      new CallbackAction({
        object: currency,
        icon: {name: 'edit', class: 'fl-icons'},
        name: $localize`Edit`,
        tooltip: $localize`Edit`,
        noPermissions: !permissions['currency.update'],
        callback: action => this.editCurrency(action),
      })
    ];

    if (!currency.is_default) {
      let tooltip = $localize`Delete`;
      if (currency.is_used) {
        tooltip = $localize`Currency cannot be\ndeleted because it is\nused by other objects`;
      }
      actions.push(
        new CallbackAction({
          object: currency,
          icon: {name: 'delete', class: 'fl-icons'},
          name: $localize`Delete`,
          tooltip,
          noPermissions: !permissions['currency.destroy'],
          confirmOptions: {
            confirm: true,
            message: $localize`Are you sure you want to delete currency ${currency.code}?`,
            title: $localize`Delete ${currency.code} currency`,
          },
          disabled: currency.is_used,
          callback: action => this.deleteCurrency(action),
        }));
    }

    return actions;
  }
}
