import { Injectable } from '@angular/core';
import { IObjectListUIService } from '@objects-view/interfaces/object-list-ui-service';
import { ConfigService } from '@shared/config/config.service';
import { IBaseFleioObjectModel } from '@fleio-api/base-model/base-fleio-object.model';
import { IPermissionsModel } from '@fleio-api/base-model/IPermissionsModel';
import { IObjectUIService } from '@objects-view/interfaces/object-ui-service';
import { FleioObjectsList } from '@fleio-api/fleio-objects-list';
import { ITableData } from '@objects-view/interfaces/table-data/table-data';
import { ColumnType } from '@objects-view/interfaces/table-data/column-definition';
import { ITableRow } from '@objects-view/interfaces/table-data/table-row';
import { IAction } from '@objects-view/interfaces/actions/action';
import { ActivityLogUIService } from './activity-log-ui.service';
import { IActivityLogModel } from '@fleio-api/utils/model/activity-log.model';
import { DateFormatterPipe } from '@shared/ui/common/pipes/date-formatter.pipe';
import { ActivityLogDetailComponent } from './tabs/activity-log-detail/activity-log-detail.component';
import * as _moment from 'moment';

@Injectable({
  providedIn: 'root'
})
export class ActivityLogListUiService implements IObjectListUIService {
  public noItemsMessage = $localize`No activity log entries`;
  private datePipe: DateFormatterPipe;
  private _showUser = true;

  constructor(
    private config: ConfigService,
  ) {
    this.datePipe = new DateFormatterPipe(this.config);
  }

  set showUser(value) {
    this._showUser = value;
  }

  get showUser() {
    return this._showUser;
  }

  getObjectUIService(
    object: IBaseFleioObjectModel, permissions: IPermissionsModel, state: string
  ): IObjectUIService {
    return new ActivityLogUIService(
      object as IActivityLogModel, permissions, state,
    );
  }

  getTooltip(activityLogEntry: IActivityLogModel): string {
    const executionDuration = _moment.duration(
      // @ts-ignore
      new Date(activityLogEntry.last_update) - new Date(activityLogEntry.created_at)
    ).locale(this.config.locale).humanize();

    const runningSince = _moment.duration(
      // @ts-ignore
      new Date() - new Date(activityLogEntry.created_at)
    ).locale(this.config.locale).humanize();

    switch (activityLogEntry.state) {
      case 'pending':
        return $localize`Running since ${runningSince} ago`;
      case 'success':
        return $localize`Successfully executed in ${executionDuration}`;
      case 'error':
        return $localize`Failed after ${executionDuration}`;
    }
  }

  getTableData(objectList: FleioObjectsList<IActivityLogModel>): ITableData {
    const columnNames = ['message', 'tasks', 'created_at', 'user', 'ip'];
    if (!this.showUser) {
      columnNames.splice(columnNames.indexOf('user'), 1);
    }
    const tableData = {
      header: {
        columns: [
          {
            type: ColumnType.Value, displayName: $localize`Message`, enableSort: false, fieldName: 'message',
            flex: '1 0 400px', flexXs: '1 1 90%', wrap: true,
          },
          {
            type: ColumnType.Value, displayName: $localize`Created at`, enableSort: true, fieldName: 'created_at',
            flex: '200px', hide: {xs: true, sm: true, md: true,},
          },
          {
            type: ColumnType.Value, displayName: $localize`Tasks`, enableSort: false, fieldName: 'tasks',
            flex: '85px', hide: 'xs',
          },
          {
            type: ColumnType.Value, displayName: $localize`User`, enableSort: true, fieldName: 'user',
            flex: '120px', hide: {xs: true, sm: true},
          },
          {
            type: ColumnType.Value, displayName: $localize`IP`, enableSort: true, fieldName: 'ip',
            flex: '150px', hide: {xs: true, sm: true},
          },
        ],
        columnNames,
        showStatus: true,
      },
      rows: [],
      expandableRows: true,
      detailComponent: ActivityLogDetailComponent,
      trackByFunction: (index, item: ITableRow) => item.object.id,
    };

    for (const activityLogEntry of objectList.objects) {
      const rowUIService = this.getObjectUIService(activityLogEntry, objectList.permissions, 'table-view');
      let subText: string;
      switch (activityLogEntry.total_operation_count) {
        case 0:
          subText = $localize`no operations`;
          break;
        case 1:
          subText = $localize`${activityLogEntry.total_operation_count} operation`;
          break;
        default:
          subText = $localize`${activityLogEntry.total_operation_count} operations`;
          break;
      }
      const row: ITableRow = {
        cells: {
          created_at: {text: this.datePipe.toDateTime(activityLogEntry.created_at)},
          tasks: {
            text: activityLogEntry.tasks_count > 0 ? $localize`${activityLogEntry.tasks_count} tasks` : $localize`no tasks`,
            subText: subText,
          },
          user: {text: activityLogEntry.user ? activityLogEntry.user.email : $localize`n/a`},
          message: {text: activityLogEntry.log, title: this.getTooltip(activityLogEntry)},
          ip: {text: activityLogEntry.ip ? activityLogEntry.ip : $localize`n/a`},
        },
        status: rowUIService.getStatus(),
        object: activityLogEntry,
        expandable: !!activityLogEntry.details || (activityLogEntry.tasks_count > 0) || (activityLogEntry.operations.length > 0),
      };

      tableData.rows.push(row);
    }

    return tableData;
  }

  getActions(objectList: FleioObjectsList<IBaseFleioObjectModel>): IAction[] {
    return [];
  }

  getRefreshInterval(): number {
    if (this.config && this.config.current && this.config.current.settings &&
      this.config.current.settings.refreshIntervals) {
      return this.config.current.settings.refreshIntervals.defaultInterval;
    }
    return 10000;
  }
}
