/**
 * Core Types - Enterprise
 * 
 * Shared types and interfaces used across the application.
 * All types are strict and null-safe.
 */

import type { ErrorCode } from '../errors';

// ============================================
// API Response Types
// ============================================

/**
 * Standard API success response
 */
export interface ApiSuccessResponse<T = unknown> {
  success: true;
  data: T;
  meta?: ResponseMeta;
}

/**
 * Standard API error response
 */
export interface ApiErrorResponse {
  success: false;
  error: {
    code: ErrorCode;
    message: string;
    details?: Record<string, string[]>;
    timestamp: string;
    correlationId?: string;
  };
  retryAfter?: number;
}

/**
 * API response type (success or error)
 */
export type ApiResponse<T = unknown> = ApiSuccessResponse<T> | ApiErrorResponse;

/**
 * Response metadata for pagination
 */
export interface ResponseMeta {
  pagination?: PaginationMeta;
  cache?: CacheMeta;
  request?: RequestMeta;
}

/**
 * Pagination metadata
 */
export interface PaginationMeta {
  page: number;
  limit: number;
  total: number;
  totalPages: number;
  hasNext: boolean;
  hasPrev: boolean;
}

/**
 * Cache metadata
 */
export interface CacheMeta {
  cached: boolean;
  ttl?: number;
  timestamp?: string;
}

/**
 * Request metadata
 */
export interface RequestMeta {
  timestamp: string;
  duration: number;
  correlationId: string;
}

// ============================================
// Pagination Types
// ============================================

/**
 * Pagination options
 */
export interface PaginationOptions {
  page: number;
  limit: number;
}

/**
 * Paginated result
 */
export interface PaginatedResult<T> {
  items: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
  hasNext: boolean;
  hasPrev: boolean;
}

// ============================================
// Sorting and Filtering Types
// ============================================

/**
 * Sort direction
 */
export type SortDirection = 'asc' | 'desc';

/**
 * Sort options
 */
export interface SortOptions<T extends string = string> {
  field: T;
  direction: SortDirection;
}

/**
 * Base filter options
 */
export interface BaseFilterOptions {
  search?: string;
  startDate?: Date;
  endDate?: Date;
}

// ============================================
// Service Layer Types
// ============================================

/**
 * Service result (monad-like pattern)
 */
export type ServiceResult<T> = 
  | { success: true; data: T; error?: never }
  | { success: false; data?: never; error: { code: ErrorCode; message: string; details?: Record<string, string[]> } };

/**
 * Service operation context
 */
export interface ServiceContext {
  userId?: string;
  correlationId: string;
  requestIp?: string;
  userAgent?: string;
}

// ============================================
// Repository Types
// ============================================

/**
 * Base repository options
 */
export interface RepositoryOptions {
  includeDeleted?: boolean;
  skipCache?: boolean;
  timeoutMs?: number;
}

/**
 * Query options
 */
export interface QueryOptions extends RepositoryOptions {
  select?: string[];
  relations?: string[];
}

// ============================================
// Event Types
// ============================================

/**
 * Domain event base
 */
export interface DomainEvent {
  type: string;
  timestamp: Date;
  correlationId: string;
  payload: Record<string, unknown>;
}

/**
 * Event handler
 */
export type EventHandler<T extends DomainEvent> = (event: T) => Promise<void> | void;

// ============================================
// Logging Types
// ============================================

/**
 * Log level
 */
export type LogLevel = 'error' | 'warn' | 'info' | 'http' | 'debug' | 'verbose';

/**
 * Log entry
 */
export interface LogEntry {
  level: LogLevel;
  message: string;
  timestamp: Date;
  correlationId?: string;
  service?: string;
  metadata?: Record<string, unknown>;
  error?: Error;
}

// ============================================
// Cache Types
// ============================================

/**
 * Cache strategy
 */
export type CacheStrategy = 'memory' | 'redis' | 'hybrid';

/**
 * Cache options
 */
export interface CacheOptions {
  ttl: number;
  strategy?: CacheStrategy;
  tags?: string[];
}

// ============================================
// Utility Types
// ============================================

/**
 * Nullable type helper
 */
export type Nullable<T> = T | null;

/**
 * Optional type helper
 */
export type Optional<T> = T | undefined;

/**
 * Deep partial type
 */
export type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

/**
 * Strict ID type
 */
export type EntityId = string;

/**
 * Timestamp fields
 */
export interface TimestampFields {
  createdAt: Date;
  updatedAt: Date;
  deletedAt: Date | null;
}

/**
 * Soft delete interface
 */
export interface SoftDeletable {
  isDeleted: boolean;
  deletedAt: Date | null;
  deletedBy: EntityId | null;
}

// ============================================
// Type Guards
// ============================================

/**
 * Check if value is non-null
 */
export function isNonNull<T>(value: T | null | undefined): value is T {
  return value !== null && value !== undefined;
}

/**
 * Check if value is a string
 */
export function isString(value: unknown): value is string {
  return typeof value === 'string';
}

/**
 * Check if value is a number
 */
export function isNumber(value: unknown): value is number {
  return typeof value === 'number' && !isNaN(value);
}

/**
 * Check if value is a Date
 */
export function isDate(value: unknown): value is Date {
  return value instanceof Date && !isNaN(value.getTime());
}
