import * as breeze from 'breeze-client';
import { RouteConfig } from 'aurelia-router';
import { ColumnState, ColDef } from 'ag-grid-community';
import { DialogBoxViewModel } from '../modules/dialogs/dialog-box';

export interface CompressorOptions {
  strict?: boolean;
  checkOrientation?;
  maxWidth?: number;
  maxHeight?: number;
  minWidth?: number;
  minHeight?: number;
  width?: number;
  height?: number;
  quality?: number;
  mimeType?: string;
  convertSize?: number;

}

export interface TranslatedProperty {
  lang1: string;
  lang2: string;
  lang3: string;
  lang4: string;
  lang5: string;
  _translation: string;
}

export interface Locality extends breeze.Entity {
  id: number;
  zipCode: string;
  name: TranslatedProperty;
  countryId: number;
  country: Country;
  communeId: number | null;
  commune: Locality;
  isSubCommune: boolean | null;
  communeName: string;
  provincieName: string;
}

export interface Country extends BaseEntityWithId {
  code: string;
  isFavorite: boolean;
  region: string;
  //european union
  isEU: boolean;
  name: TranslatedProperty;
}

export class UserProfile {
  public id: number;
  public firstName: string;
  public lastName: string;
  public fullName: string;
  public username: string;
  public email: string;
  public language: string;
  public roles: number[];
  public settings: UserSettings;
  public avatarUri: string;
  public permissions: string[];
  public userData: any;

  get sanitizedSettings(): any {
    // on fait une copie identique de l'objet afin de supprimer une propriété sans toucher à l'objet d'origine
    var obj = jQuery.extend(true, {}, this.settings);

    obj.customSearchList.forEach(x => {
      if (x.navModel)
        delete x.navModel;
    });

    return obj;
  }

  constructor(userData: any) {
    this.id = userData.id;
    this.firstName = userData.firstName;
    this.lastName = userData.lastName;
    this.fullName = userData.fullName;
    this.username = userData.username;
    this.email = userData.email;
    if (userData.roleId != null) {
      this.roles = [userData.roleId];
    }
    else if (userData.roles != null && isArray(userData.roles)) {
      this.roles = (userData.roles as Array<UserRole>).map(x => x.roleId);
    }
    else {
      this.roles = [];
    }
    this.language = userData.languageCode;
    this.userData = userData;
    if (userData.permissions != null) {
      this.permissions = userData.permissions.replace(/-/g, '').split(";");
    }

    try {
      this.settings = JSON.parse(userData.settings);
    } catch (e) {
      console.log(e);
    } finally {

      let sessionsSettings = sessionStorage.getItem(`user-settings-${this.id}`);
      if (sessionsSettings != null) {
        this.settings = JSON.parse(sessionsSettings) as UserSettings;
      }
      // Ensure default format
      this.settings = Object.assign({
        customSearchList: [],
        dataGridSettings: {}
      }, this.settings);
    }
  }
}

export interface IAuditable {
  createdById: number | null;
  createdBy: User;
  createdTime: Date;
  updatedById: number | null;
  updatedBy: User;
  updatedTime: Date | null;
}

export interface User extends BaseEntityWithId {
  externalId: string;
  username: string;
  email: string;
  disabled: boolean;
  settings: string;
  languageCode: string;
  permissions: string;
  isSystemUser: boolean;
  firstName: string;
  lastName: string;
  fullName: string;
  tenantId: string | null;
  picture: string;
  avatarUri: string;
  isAuth0SocialConnection: boolean;

  notificationByPush: boolean | null;
  notificationByEmail: boolean | null;
  notificationAbsractByEmail: boolean | null;

  messagesCreated: ChatMessage[];
  messagesReferencedIn: ChatMessageUser[];

  notificationsCreated: Notification[];
  notifiedIn: Notification[];

  roles: UserRole[];
}

export interface UserRole extends breeze.Entity, IAuditable {
  userId: number;
  user: User;

  roleId: number;
  role: Role;

  createdByFullName: string;
  updatedByFullName: string;
}

export interface Role extends BaseEntityWithIdAndActive {
  externalId: string;
  internalId: string;
  name: TranslatedProperty;
  description: TranslatedProperty;
  isLocked: boolean;

  users: UserRole[];
  permissions: RolePermission[];
}

export interface RolePermission extends breeze.Entity, IAuditable {
  roleId: number;
  role: Role;

  permissionId: string;
  permission: Permission;

  createdByFullName: string;
  updatedByFullName: string;
}

export interface Permission extends breeze.Entity {
  permissionId: string;
  isLocked: boolean;
}

export interface UserSettings {
  customSearchList?: RouteConfig[];
  dataGridSettings?: DataGridSettings;
  customSettings?: any;
}

export interface DataGridSettings {
  [name: string]: DataGridSetting;
}

export interface DataGridSetting {
  usedView?: UsedView;
  fixedFilters?: boolean;
  adjustColumns?: boolean;
  colsState?: ColumnState[];
  filterModel?: any;
}

export interface UsedView {
  id: number;
  name: string;
}

export interface Language extends breeze.Entity {
  code: string;
  columnIndex: number;
  name: string;

  //define property
  _columnName: string;
}

export type ViewVisibilityEnum = "System" | "Public" | "Private" | "Shared";
export type DisplayMode = "Vertical" | "Horizontal";

export interface AgGridView extends breeze.Entity, IAuditable {
  id: number;
  name: string;
  moduleId: string;
  fixedFilters: boolean;
  adjustColumns: boolean;
  columnState: string;
  filterModel: string;
  sortModel: string;
  visibility: ViewVisibilityEnum;
  authorId: number;
  author: User;
  isDefaultView: boolean;

  hide: boolean;
  used: boolean;
  agGridViewUsers: Array<AgGridViewUser>;
}

export interface AgGridViewUser extends BaseEntityWithId {
  agGridViewId: number;
  agGridView: AgGridView;
  userId: number;
  user: User;
}

export interface EnumerationType extends breeze.Entity, IAuditable {
  id: number;
  active: boolean;
  denomination: TranslatedProperty;
  category: number;
  uniqueCode: string;
  default: boolean;
  textColor: string;
  backgroundColor: string;
  order: number;
  isEditable: boolean;
}

export interface EnumerationTypeColor extends breeze.Entity {
  id: number;
  description: TranslatedProperty;
  textColor: string;
  backgroundColor: string;
}

export interface ValueSelected {
  id: number;
  name: string;
  selected: boolean;

  hide: boolean;
}

export interface EnumSelected {
  index: number;
  key: string;
  selected: boolean;

  hide: boolean;
}

export interface BaseEntityWithId extends breeze.Entity, IAuditable {
  id: number;
}
export interface IFile extends BaseEntityWithId {
  url: string;
  name: string;
  description: string;
  fileTypeId: number | null;
  fileType: EnumerationType;
  size: number;
}

export interface BaseEntityWithIdAndActive extends BaseEntityWithId {
  active: boolean;
}

export enum FieldType {
  Base = "Base",
  String = "String",
  Number = "Number",
  Date = "Date",
  DateTime = "DateTime",
  Boolean = "Boolean",
  Enumeration = "Enumeration",
  Enum = "Enum",
  Html = "Html",
  User = "User",
  ManyToMany = "ManyToMany",
  Currency = "Currency",
  OneToMany = "OneToMany"
}

export enum FilterDatePreset {
  Past = 0,
  Today = 1,
  Futur = 2,
  IsLastMonth = 3,
  IsLastWeek = 4,
  IsThisWeek = 5,
  IsThisMonth = 6,
  IsNextWeek = 7,
  IsNextMonth = 8

}
export class Various {
  public static NewId = -100;
  public static DateFormat = "DD/MM/YYYY";
  public static DateFormatWithHours = "DD/MM/YYYY HH:mm";
}

export enum DatePreFilter {
  None, Today/*, ThisWeek, NextWeek, ThisMonth, NextMonth, LastWeek, LastMonth*/, Past, Futur
}

export enum UserPreFilter {
  None, Me, NotMe
}

export class TimeInMilliseconds {
  public static DayInMilliseconds: number = 86400000;
  public static WeekInMilliseconds: number = 604800000;
}

export interface UIMenuGroupConfig {
  icon?: string;
  separators?: Array<UIMenuGroupSeparator>;
  isBottom?: boolean;
  isDefault?: boolean;
  defaultSubGroup?: string;
  alwaysGroup?: boolean;
  classes?: string;
}

export class UIMenuGroupSeparator {
  public static Blank = "blank";
  public static Line = "line";
}

export interface EmailTemplate extends breeze.Entity, IAuditable {
  id: number;
  emailTitle: string;
  emailBody: string;
  fromEmailAddress: string;
  fromName: string;
  ccEmailAddress: string;
  languageId: number | null;
  language: EnumerationType;
  emailTypeId: number;
  emailType: EnumerationType;
}

export interface EmailToken extends breeze.Entity {
  id: number;
  tokenName: string;
  tokenDescription: TranslatedProperty;
  emailTypeId: number;
  emailType: EnumerationType
}

export interface AuditLog extends breeze.Entity {
  Id: number;
  DateTime: Date;
  EntityPK: number;
  ClrEntityType: string;
  ActionType: string;
  AuditUser: string;
  DisplayType: string;
  Display: string;
  LinkEntityType: string;
  LinkEntityPK: number | null;
  Changes: AuditLogChanges[];
  ShowDetails: boolean;
  Link: string;
  Icon: string;
}

export interface AuditLogChanges {
  PropertyName: string;
  NewValue: any;
  OldValue: any;
}
export class AuditLogCustom {
  entitiesIcons: Array<AuditLogIcon>;
  entitiesSpecificType: AuditLogEntitySpecificType;
}
export class AuditLogEntitySpecificType {
  file: Array<string>;
  picture: Array<string>;
  comment: Array<string>;
}
export class AuditLogIcon {
  entityName: string;
  icon: string;
}

export enum FilterMode {
  Or, And
}

/* --- CHAT --- */
export interface Notification extends BaseEntityWithId {
  notificationSubjetHTML: string;
  notificationContentHTML: string;
  diplayedDateTime: Date | string | null;
  pushedDateTime: Date | string | null;
  emailSentDateTime: Date | string | null;

  generatedFromId: number | null;
  generatedFrom: ChatMessage;
  notifiedById: number | null;
  notifiedBy: User;
  notifiedUserId: number;
  notifiedUser: User;

  //not in DB
  isRead: boolean
}

export interface ChatEntity extends BaseEntityWithId {
  entityName: string;
  entityId: number;
  chatMessages: ChatMessage[];
}

export interface ChatMessage extends BaseEntityWithId {
  messageML: string;
  chatEntityId: number;
  chatEntity: ChatEntity;
  referencedUsers: User[];
  notifications: Notification[];

  //not in DB
  showEdit: boolean;
  showButton: boolean;
  firstMessageOfTheDay: boolean;
  isMyMessage: boolean;
}

export interface ChatMessageUser {
  id: number;
  userId: number;
  user: User;
  chatMessageId: number;
  chatMessage: ChatMessage;
}


export interface ActionDialogBoxInputParameters {
  label?: string;
  title?: string;
  icon?: string;
  theme?: string;
  closeDialog?: boolean;
  type?: string;
  disabled?: boolean;
  class?: string;
  fn: string | ((dialogBox?: DialogBoxViewModel) => Promise<any> | any);
  keyboardShortcut?: string | string[];
}

export interface ChatMessageDTO {
  message: string;
  messageId: number | null;
  creatorId: number | null;
  entityId: number;
  entityName: string;
  route: string;
}

export interface UIFilesColumnInfo {
  columnName: string;
  columnVisibility: boolean;
  width: number | string | 'fit-content';
}

export interface CustomColDef<TData = any> extends ColDef<TData> {
  hideInParameter?: boolean;
  viewMovable?: boolean;
}

export interface CsvExportConfig {
  useConfirmDialog: boolean,
  export: () => Promise<void> | void
}


export enum ImportDefaultValueType {
  Input = 0,
  Date,
  Select
}


export const LocalityRessourceName = "Locality";
