import { IPermissionsModel } from '@fleio-api/base-model/IPermissionsModel';
import { IIcon } from '@shared/ui/common/interfaces/icon';
import { ITitle } from '@objects-view/interfaces/card-data/card-title';
import { IObjectStatus, StatusType, StatusValue } from '@objects-view/interfaces/object-status';
import { ObjectUIServiceBase } from '@objects-view/object-ui-service-base';
import { IAction } from '@objects-view/interfaces/actions/action';
import { Router } from '@angular/router';
import { ConfigService } from '@shared/config/config.service';
import { IDataField } from '@objects-view/interfaces/card-data/data-field';
import { IDetailsTab } from '@objects-view/interfaces/details/details-tab';
import { MatDialog } from '@angular/material/dialog';
import { IJournalEntryModel } from '@fleio-api/billing/model/journal-entry.model';
import { JournalsApiService } from '@fleio-api/billing/journal/journal-api.service';
import { ApiCallAction, CallType } from '@objects-view/actions/api-call-action';
import { CallbackAction } from '@objects-view/actions/callback-action';
import { of } from 'rxjs';
import { NotificationService } from '@shared/ui-api/notification.service';
import { GatewayApiService } from '@fleio-api/billing/gateways/gateway-api.service';
import {
  JournalDetailsOverviewComponent
} from '../../../../../staff/billing/journal/tabs/journal-details-overview/journal-details-overview.component';


export class CommonJournalUiService extends ObjectUIServiceBase<IJournalEntryModel> {
  protected readonly router: Router;
  protected readonly config: ConfigService;
  protected readonly journalsApiService: JournalsApiService;
  protected readonly matDialog: MatDialog;
  protected readonly gatewayApiService: GatewayApiService;
  protected readonly notificationService: NotificationService;

  constructor(
    journal: IJournalEntryModel, permissions: IPermissionsModel, state: string,
    router: Router, config: ConfigService, journalsApiService: JournalsApiService, matDialog: MatDialog,
    gatewayApiService: GatewayApiService, notificationService: NotificationService
  ) {
    super(journal, permissions, state);
    this.matDialog = matDialog;
    this.router = router;
    this.config = config;
    this.journalsApiService = journalsApiService;
    this.gatewayApiService = gatewayApiService;
    this.notificationService = notificationService;
  }

  getIcon(): IIcon {
    return null;
  }

  getStatus(): IObjectStatus {
    return {type: StatusType.None, value: StatusValue.None};
  }

  getTitle(): ITitle {
    switch (this.state) {
      case 'details':
        return {
          text: $localize`Journal details`
        };
      default:
        return {
          text: `${this.object.id}`,
        };
    }
  }

  getActions(): IAction[] {
    const actions: IAction[] = [];

    if (this.object && this.object.transaction && this.object.transaction.actions &&
      Array.isArray(this.object.transaction.actions)) {
      for (const action of this.object.transaction.actions) {
        let actionIcon = 'play_arrow';
        if (action.name === 'refund') {
          actionIcon = 'undo';
        }
        if (action.redirect) {
          actions.push(new CallbackAction(
            {
              object: this.object,
              icon: {name: actionIcon},
              tooltip: action.display,
              name: action.name,
              callback: () => {
                if (action.name === 'capture') {
                  this.config.authService.generateOtpToken().subscribe(token => {
                    const query = `fleio-token=${token}&invoice=${this.object.invoice}&transaction=${this.object.transaction.id}`;
                    let redirectUrl = this.config.getPanelApiUrl('billing/gateway/');
                    redirectUrl += action.gateway + '/' + action.name + '?' + query;
                    window.location.href = redirectUrl;
                  });
                } else {
                  this.notificationService.confirmDialog(
                    {
                      title: $localize`${action.display} transaction`,
                      message: $localize`Do you want to ${action.display.toLowerCase()} transaction?`
                    }
                  ).subscribe(result => {
                    if (result?.button === 'yes') {
                      this.config.authService.generateOtpToken().subscribe(token => {
                        const query = `fleio-token=${token}&invoice=${this.object.invoice}&transaction=${this.object.transaction.id}`;
                        let redirectUrl = this.config.getPanelApiUrl('billing/gateway/');
                        redirectUrl += action.gateway + '/' + action.name + '?' + query;
                        window.location.href = redirectUrl;
                      });
                    }
                  });
                }
                return of(null);
              }
            }
          ));
        } else {
          actions.push(new ApiCallAction({
            icon: {name: actionIcon},
            tooltip: action.display,
            name: action.name,
            confirmOptions: {
              confirm: true,
              title: $localize`${action.display} transaction`,
              message: $localize`Do you want to ${action.display.toLowerCase()} transaction?`,
            },
            object: this.object,
            apiService: this.gatewayApiService,
            callType: CallType.Post,
            apiAction: action.name,
            endpointIdentifier: action.gateway,
            apiParams: {
              invoice: this.object.invoice,
              transaction: this.object.transaction.id
            },
          }));
        }
      }
    }

    return actions;
  }

  getDetailsLink(): string {
    return this.config.getPanelUrl(`billing/journal/${this.object.id}`);
  }

  getCardFields(): IDataField[] {
    return [];
  }

  getTabs(): IDetailsTab[] {
    switch (this.state) {
      case 'details':
        return [
          {
            tabName: $localize`Overview`,
            tabIdentifier: 'overview',
            component: JournalDetailsOverviewComponent
          }
        ];
      default:
        return [];
    }
  }

  getCardTags(): string[] {
    return [];
  }

  getDetailsActions(): IAction[] {
    return [];
  }

  getObjectDetailsRefreshInterval(): number {
    switch (this.state) {
      case 'details':
        return this.config.getDefaultRefreshInterval(true);
      default:
        return null;
    }
  }
}
