/**
 * Sync Types and Interfaces
 * TypeScript definitions for sync operations
 */

// Entity types that can be synced from Autotask
export enum EntityType {
  COMPANIES = 'companies',
  TICKETS = 'tickets',
  TASKS = 'tasks',
  PROJECTS = 'projects',
  RESOURCES = 'resources',
  STATUSES = 'statuses',
  ISSUE_TYPES = 'issue_types',
  SUB_ISSUE_TYPES = 'sub_issue_types',
  WORK_TYPES = 'work_types',
  QUEUES = 'queues',
  PRIORITIES = 'priorities',
  TICKET_CATEGORIES = 'ticket_categories',
  BILLING_ITEMS = 'billing_items',
  CONFIGURATION_ITEMS = 'configuration_items',
  CONTACTS = 'contacts',
  CONTRACTS = 'contracts',
  CONTRACT_SERVICES = 'contract_services',
  AUTOTASK_SERVICES = 'autotask_services',
  TIME_ENTRIES = 'time_entries',
  TICKET_NOTES = 'ticket_notes',
  TAG_GROUPS = 'autotask_tag_groups',
  TAGS = 'autotask_tags',
  PROJECT_PHASES = 'project_phases',
  COMPANY_CATEGORIES = 'company_categories',
  COMPANY_TYPES = 'company_types',
  COMPANY_TEAMS = 'company_teams',
}

// Sync operation types
export enum SyncType {
  FULL = 'full',
  INCREMENTAL = 'incremental',
  ENTITY_SPECIFIC = 'entity-specific',
}

// Sync status
export enum SyncStatus {
  STARTED = 'started',
  IN_PROGRESS = 'in_progress',
  COMPLETED = 'completed',
  FAILED = 'failed',
}

// Sync configuration
export interface SyncConfig {
  entities: EntityType[];
  syncType: SyncType;
  triggeredBy?: string;
  batchSize?: number;
  rateLimit?: number; // requests per second
  yearsBack?: number; // Number of years to look back for time-based entities (default: 2)
}

// Sync progress information
export interface SyncProgress {
  syncId: string;
  entityType: EntityType;
  status: SyncStatus;
  currentPage?: number;
  totalPages?: number;
  recordsProcessed: number;
  recordsAdded: number;
  recordsUpdated: number;
  recordsDeleted: number;
  startedAt: Date;
  estimatedCompletion?: Date;
  error?: string;
  // Chunking support
  currentChunk?: number;
  totalChunks?: number;
  chunkDescription?: string; // e.g., "Jan 2024"
}

// Chunk progress for detailed tracking
export interface ChunkProgress {
  chunkIndex: number;
  totalChunks: number;
  startDate: Date;
  endDate: Date;
  description: string; // e.g., "January 2024"
  status: 'pending' | 'in_progress' | 'completed' | 'failed';
  recordsProcessed: number;
  error?: string;
}

// Sync history record (matches database table)
export interface SyncHistory {
  id: number;
  entity_type: string;
  sync_type: SyncType;
  status: SyncStatus;
  started_at: Date;
  completed_at?: Date;
  records_added: number;
  records_updated: number;
  records_deleted: number;
  error_message?: string;
  triggered_by?: string;
}

// Alias for database compatibility
export interface SyncHistoryRecord {
  id: number;
  entity_type: string;
  sync_type: SyncType;
  status: SyncStatus;
  started_at: Date;
  completed_at?: Date;
  records_added: number;
  records_updated: number;
  records_deleted: number;
  error_message?: string;
  triggered_by?: string;
}

// Sync result for a single entity
export interface EntitySyncResult {
  entityType: EntityType;
  success: boolean;
  recordsAdded: number;
  recordsUpdated: number;
  recordsDeleted: number;
  duration: number; // milliseconds
  error?: string;
}

// Overall sync result
export interface SyncResult {
  syncId: string;
  syncType: SyncType;
  status: SyncStatus;
  entities: EntitySyncResult[];
  totalRecordsAdded: number;
  totalRecordsUpdated: number;
  totalRecordsDeleted: number;
  startedAt: Date;
  completedAt?: Date;
  duration?: number; // milliseconds
  errors: string[];
}

// Sync state (stored in Redis for real-time updates)
export interface SyncState {
  syncId: string;
  status: SyncStatus;
  progress: SyncProgress[];
  startedAt: Date;
  lastUpdated: Date;
}

// Entity dependency map (for determining sync order)
export const ENTITY_DEPENDENCIES: Record<EntityType, EntityType[]> = {
  [EntityType.COMPANIES]: [], // No dependencies
  [EntityType.RESOURCES]: [], // No dependencies
  [EntityType.STATUSES]: [], // No dependencies
  [EntityType.ISSUE_TYPES]: [], // No dependencies
  [EntityType.SUB_ISSUE_TYPES]: [], // No dependencies
  [EntityType.WORK_TYPES]: [], // No dependencies
  [EntityType.QUEUES]: [], // No dependencies
  [EntityType.PRIORITIES]: [], // No dependencies
  [EntityType.TICKET_CATEGORIES]: [], // No dependencies
  [EntityType.CONTACTS]: [EntityType.COMPANIES], // Depends on companies
  [EntityType.PROJECTS]: [EntityType.COMPANIES, EntityType.RESOURCES], // Depends on companies and resources
  [EntityType.TICKETS]: [EntityType.COMPANIES, EntityType.RESOURCES, EntityType.CONTACTS], // Depends on companies, resources, contacts
  [EntityType.TASKS]: [EntityType.RESOURCES, EntityType.PROJECTS, EntityType.TICKETS], // Depends on resources, projects, tickets
  [EntityType.CONFIGURATION_ITEMS]: [EntityType.COMPANIES, EntityType.CONTACTS], // Depends on companies and contacts
  [EntityType.CONTRACTS]: [EntityType.COMPANIES, EntityType.CONTACTS], // Depends on companies and contacts
  [EntityType.CONTRACT_SERVICES]: [EntityType.CONTRACTS], // Depends on contracts
  [EntityType.AUTOTASK_SERVICES]: [], // No dependencies — standalone lookup
  [EntityType.BILLING_ITEMS]: [EntityType.COMPANIES, EntityType.TASKS, EntityType.TICKETS, EntityType.PROJECTS], // Depends on multiple entities
  [EntityType.TIME_ENTRIES]: [EntityType.COMPANIES, EntityType.RESOURCES, EntityType.CONTACTS, EntityType.PROJECTS, EntityType.TASKS, EntityType.TICKETS], // Depends on many entities
  [EntityType.TICKET_NOTES]: [EntityType.TICKETS], // Depends on tickets
  [EntityType.TAG_GROUPS]: [], // No dependencies — standalone lookup
  [EntityType.TAGS]: [EntityType.TAG_GROUPS], // Depends on tag groups (FK)
  [EntityType.PROJECT_PHASES]: [EntityType.PROJECTS], // Depends on projects
  [EntityType.COMPANY_CATEGORIES]: [], // No dependencies — standalone lookup
  [EntityType.COMPANY_TYPES]: [], // No dependencies — standalone lookup
  [EntityType.COMPANY_TEAMS]: [EntityType.COMPANIES, EntityType.RESOURCES], // Depends on companies and resources
};

// Autotask API field names (for incremental sync)
export interface AutotaskQueryFilter {
  field: string;
  op: 'eq' | 'noteq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'beginsWith' | 'endsWith';
  value: any;
}

// Autotask query options
export interface AutotaskQueryOptions {
  filters?: AutotaskQueryFilter[];
  pageSize?: number;
  includeFields?: string[];
  maxRecords?: number;
}

// Last sync information per entity
export interface LastSyncInfo {
  entityType: EntityType;
  lastSyncTime?: Date;
  lastSyncStatus: SyncStatus;
  recordCount: number;
}

// Sync notification
export interface SyncNotification {
  syncId: string;
  type: 'success' | 'failure' | 'warning';
  message: string;
  entityType?: EntityType;
  timestamp: Date;
}
