/**
 * Calendar Type Definitions
 */

import { IWeekSchedule } from './ScheduleTypes';

export type SyncStatus = 'synced' | 'pending' | 'error';

export type EntityType = 'Event' | 'Booking' | 'Customer' | 'Resource' | 'Team' | 'Department' | 'Audit' | 'Settings' | 'ViewConfig';

/**
 * CalendarEventType - Used by ICalendarEvent.type
 * Note: Only 'customer' events have associated IBooking
 */
export type CalendarEventType =
  | 'customer'    // Customer appointment (HAS booking)
  | 'vacation'    // Vacation/time off (NO booking)
  | 'break'       // Lunch/break (NO booking)
  | 'meeting'     // Meeting (NO booking)
  | 'blocked';    // Blocked time (NO booking)

/**
 * ISync - Interface for sync status tracking
 * All syncable entities should extend this interface
 */
export interface ISync {
  syncStatus: SyncStatus;
}

/**
 * IDataEntity - Wrapper for entity data with typename discriminator
 */
export interface IDataEntity {
  typename: EntityType;
  data: unknown;
}

export interface ICalendarEvent extends ISync {
  id: string;
  title: string;
  description?: string;
  start: Date;
  end: Date;
  type: CalendarEventType;
  allDay: boolean;

  // References (denormalized for IndexedDB performance)
  bookingId?: string;        // Reference to booking (only if type = 'customer')
  resourceId?: string;       // Resource who owns this time slot
  customerId?: string;       // Denormalized from Booking.customerId

  recurringId?: string;
  metadata?: Record<string, unknown>;
}

// EventBus types
export interface IEventLogEntry {
  type: string;
  detail: unknown;
  timestamp: number;
}

export interface IListenerEntry {
  eventType: string;
  handler: EventListener;
  options?: AddEventListenerOptions;
}

export interface IEventBus {
  on(eventType: string, handler: EventListener, options?: AddEventListenerOptions): () => void;
  once(eventType: string, handler: EventListener): () => void;
  off(eventType: string, handler: EventListener): void;
  emit(eventType: string, detail?: unknown): boolean;
  getEventLog(eventType?: string): IEventLogEntry[];
  setDebug(enabled: boolean): void;
}

// Entity event payloads
export interface IEntitySavedPayload {
  entityType: EntityType;
  entityId: string;
  operation: 'create' | 'update';
  changes: unknown;
  timestamp: number;
}

export interface IEntityDeletedPayload {
  entityType: EntityType;
  entityId: string;
  operation: 'delete';
  timestamp: number;
}

// Event update payload (for re-rendering columns after drag/resize)
export interface IEventUpdatedPayload {
  eventId: string;
  sourceColumnKey: string;      // Source column key (where event came from)
  targetColumnKey: string;      // Target column key (where event landed)
}

// Resource types
export type ResourceType =
  | 'person'
  | 'room'
  | 'equipment'
  | 'vehicle'
  | 'custom';

export interface IResource extends ISync {
  id: string;
  name: string;
  displayName: string;
  type: ResourceType;
  avatarUrl?: string;
  color?: string;
  isActive?: boolean;
  defaultSchedule?: IWeekSchedule;  // Default arbejdstider per ugedag
  metadata?: Record<string, unknown>;
}

// Team types
export interface ITeam extends ISync {
  id: string;
  name: string;
  resourceIds: string[];
}

// Department types
export interface IDepartment extends ISync {
  id: string;
  name: string;
  resourceIds: string[];
}

// Booking types
export type BookingStatus =
  | 'created'
  | 'arrived'
  | 'paid'
  | 'noshow'
  | 'cancelled';

export interface IBookingService {
  serviceId: string;
  serviceName: string;
  baseDuration: number;
  basePrice: number;
  customPrice?: number;
  resourceId: string;
}

export interface IBooking extends ISync {
  id: string;
  customerId: string;
  status: BookingStatus;
  createdAt: Date;
  services: IBookingService[];
  totalPrice?: number;
  tags?: string[];
  notes?: string;
}

// Customer types
export interface ICustomer extends ISync {
  id: string;
  name: string;
  phone: string;
  email?: string;
  metadata?: Record<string, unknown>;
}
