import { ChangeDetectorRef, Component, NgZone, OnInit } from '@angular/core';
import { DetailsComponentBase } from '@objects-view/details-component-base';
import { ConfigService } from '@shared/config/config.service';
import { IClientModel } from '@fleio-api/client-user/model/client.model';
import { MatDialog } from '@angular/material/dialog';
import { IAction } from '@objects-view/interfaces/actions/action';
import { CallbackAction } from '@objects-view/actions/callback-action';
import {
  ChangeUserRolesDialogComponent
} from '@shared/common-dialogs/clients-users/clients/change-user-roles-dialog/change-user-roles-dialog.component';
import { map } from 'rxjs/operators';
import { IActionResult } from '@objects-view/interfaces/actions/action-result';
import { UsersApiService } from '@fleio-api/client-user/user/users-api.service';
import { ApiCallAction, CallType } from '@objects-view/actions/api-call-action';
import { AuthService } from '@shared/auth/auth.service';
import { LineColorPipe } from '@shared/ui/objects-view/status-line/line-color.pipe';
import { LineDirection, LineType } from '@shared/ui/objects-view/status-line/status-line.component';
import { IObjectStatus, StatusType, StatusValue } from '@objects-view/interfaces/object-status';
import { AssociateClientDialogComponent } from './dialogs/associate-client-dialog/associate-client-dialog.component';

@Component({
  selector: 'app-user-details-clients',
  templateUrl: './user-details-clients.component.html',
  styleUrls: ['./user-details-clients.component.scss']
})
export class UserDetailsClientsComponent extends DetailsComponentBase<IClientModel> implements OnInit {
  displayedColumns: string[];
  clientActions = {};
  clients: IClientModel[];

  private lineColorPipe: LineColorPipe;
  protected readonly LineType = LineType;
  protected readonly LineDirection = LineDirection;

  constructor(
    private usersApi: UsersApiService,
    public config: ConfigService,
    private matDialog: MatDialog,
    ngZone: NgZone,
    changeDetectorRef: ChangeDetectorRef,
    public auth: AuthService,
  ) {
    super(ngZone, changeDetectorRef, config);
    this.lineColorPipe = new LineColorPipe();
    if (this.auth.feature('clients&users.roles')) {
      this.displayedColumns = ['name', 'roles', '(actions)'];
    } else {
      this.displayedColumns = ['name', '(actions)'];
    }
  }

  ngOnInit() {
    super.ngOnInit();
  }

  getClientStatus(client): IObjectStatus {
    switch (client.status) {
      case 'active':
        return {type: StatusType.Defined, value: StatusValue.Active};
      case 'inactive':
        return {type: StatusType.Defined, value: StatusValue.Disabled};
      case 'suspending':
        return {type: StatusType.Changing, value: StatusValue.Suspended};
      case 'suspended':
        return {type: StatusType.Defined, value: StatusValue.Suspended};
      case 'deleting':
        return {type: StatusType.Changing, value: StatusValue.Deleted};
      default:
        return {type: StatusType.None, value: StatusValue.None};
    }
  }

  protected refreshData() {
    this.usersApi.getClients(this.object.id).subscribe(clients => {
      this.clients = clients.clients;
      this.clientActions = {};
      for (const client of this.clients) {
        this.clientActions[client.id] = this.getClientActions(client);
        let clientStatus = this.getClientStatus(client);
        (client as any).appLineColor = this.lineColorPipe.transform(clientStatus.value);
        (client as any).appLineType = clientStatus.type === StatusType.Changing ? LineType.Progress : LineType.Solid;
      }
    });
  }

  getClientActions(client: IClientModel): IAction[] {
    const actions = [];

    actions.push(
      new CallbackAction({
        featureName: 'clients&users.roles',
        object: this.object,
        icon: {name: 'rule'},
        tooltip: 'Edit roles',
        name: 'Edit roles',
        callback: () => this.matDialog.open(
          ChangeUserRolesDialogComponent, {
            data: {user: this.object, client, existingRoles: client.roles},
            autoFocus: false,
          }).afterClosed().pipe(map(result => {
          if (result === false) {
            return;
          }
          this.refreshData();
          return {message: result} as IActionResult;
        }))
      })
    );

    actions.push(new ApiCallAction({
        icon: {name: 'link_off'},
        tooltip: $localize`Dissociate client`,
        name: $localize`Dissociate client`,
        confirmOptions: {
          confirm: true,
          title: $localize`Dissociate client`,
          message: $localize`Are you sure you want to dissociate client ${client.display}?`,
        },
        object: this.object,
        apiService: this.usersApi,
        callType: CallType.Post,
        apiAction: 'dissociate_client',
        apiParams: {
          id: this.object.id,
          client_id: client.id,
        },
        postExecuteCallback: () => {
          this.refreshData();
        },
      })
    );

    return actions;
  }

  associateNewClient() {
    this.matDialog.open(
      AssociateClientDialogComponent, {
        data: {user: this.object},
        autoFocus: false,
      }
    ).afterClosed().subscribe(result => {
      if (result) {
        this.refreshData();
      }
    });
  }
}
