import { NucliaOptions } from '@nuclia/core';
import { Observable } from 'rxjs';
import { ColoredLabel } from '@flaps/common';

export const baseLogoPath = 'assets/connector-logos';

export const CONNECTOR_ID_KEY = 'NUCLIA_CONNECTOR_ID';
export const SOURCE_NAME_KEY = 'NUCLIA_SOURCE_NAME';
export const CONNECTOR_PARAMS_CACHE = 'CONNECTOR_PARAMS_CACHE';

export interface ConnectorDefinition {
  id: string;
  title: string;
  logo: string;
  description: string;
  helpUrl?: string;
  permanentSyncOnly?: boolean;
  deprecated?: boolean;
  cloud?: boolean;
  oauth_provider?: string;
  apikey_provider?: string;
  factory: (data?: ConnectorSettings) => IConnector;
}

export interface IConnectorBase {
  hasServerSideAuth: boolean;
  isExternal: boolean;
  allowToSelectFolders: boolean;
  canSyncSecurityGroups: boolean;
  canSyncLastChanges: boolean;
}

export interface IConnector extends IConnectorBase {
  getParametersSections(): Observable<Section[]>;
  handleParameters?(params: ConnectorParameters): void;
  getParametersValues(): ConnectorParameters;
  getLink?(resource: SyncItem): Observable<{ uri: string; extra_headers: { [key: string]: string } }>;
  getStaticFolders(): SyncItem[];
}

export enum FileStatus {
  PENDING = 'PENDING',
  PROCESSING = 'PROCESSING',
  UPLOADED = 'UPLOADED',
  ERROR = 'ERROR',
}

export interface SyncItem {
  uuid: string;
  title: string;
  originalId: string;
  metadata: { [key: string]: string };
  status: FileStatus;
  error?: string;
}

export interface SearchResults {
  items: SyncItem[];
  nextPage?: Observable<SearchResults>;
}

export interface ConnectorSettings {
  [key: string]: any;
}

export interface ConnectorParameters {
  [key: string]: any;
}

export interface Section {
  id: string;
  title: string;
  description?: string;
  badge?: string;
  fields: Field[];
}

export interface Field {
  id: string;
  label: string;
  help?: string;
  placeholder?: string;
  type: 'text' | 'select' | 'textarea' | 'table' | 'boolean' | 'file' | 'hint';
  options?: { label: string; value: string; disabled?: boolean }[];
  required?: boolean;
  pattern?: string | RegExp;
  canBeRefreshed?: boolean;
  secret?: boolean;
  accept?: string;
  handleFile?: (file: File) => Observable<any>;
}

export interface Filters {
  fileExtensions?: {
    extensions: string;
    exclude?: boolean;
  };
  modified?: {
    from?: string;
    to?: string;
  };
}

export interface FileFilter {
  mode: 'include' | 'exclude';
  extensions?: string[];
  glob_patterns?: string[];
}

export interface ModifiedTimeRange {
  from?: string;
  to?: string;
}

export type Connector = {
  name: string;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  parameters: { [key: string]: any };
};

export interface ISyncEntity {
  connector: Connector;
  connectorId?: string;
  kb?: NucliaOptions;
  labels?: ColoredLabel[];
  preserveLabels?: boolean;
  title: string;
  id: string;
  foldersToSync?: SyncItem[];
  filters?: Filters;
  lastSyncGMT?: string;
  disabled?: boolean;
  syncSecurityGroups?: boolean;
  extract_strategy?: string;
  isCloud?: boolean;
  file_filter?: FileFilter;
  modified_time_range?: ModifiedTimeRange;
}

export interface SyncBasicData {
  id: string;
  kbId: string;
  title: string;
  connectorId?: string;
  connector?: IConnectorBase;
  lastSyncGMT?: string;
  disabled?: boolean;
  totalSyncedResources?: number;
}

export enum LogSeverityLevel {
  low = 'low',
  medium = 'medium',
  high = 'high',
}

export interface LogEntity {
  level: LogSeverityLevel;
  message: string;
  createdAt: string;
  origin: string;
  action: string;
  payload: { [key: string]: any };
}
