/**
 * Shared TypeScript Types
 *
 * Type definitions used across the application
 * that complement Prisma generated types
 */

import { TopicType, ExerciseType, ExerciseDifficulty } from '@prisma/client';

// ============================================
// API REQUEST/RESPONSE TYPES
// ============================================

export interface ApiResponse<T = any> {
  success: boolean;
  data?: T;
  error?: {
    code: string;
    message: string;
    details?: any;
  };
  meta?: {
    timestamp: string;
    requestId?: string | undefined;
    version?: string | undefined;
  };
}

export interface PaginationParams {
  page?: number;
  limit?: number;
  sortBy?: string;
  sortOrder?: 'asc' | 'desc';
}

export interface PaginatedResponse<T> {
  data: T[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasNext: boolean;
    hasPrev: boolean;
  };
}

// ============================================
// AUTH TYPES
// ============================================

export interface JwtPayload {
  userId: string;
  email: string;
  username: string;
  role: string;
  iat?: number;
  exp?: number;
}

export interface AuthTokens {
  accessToken: string;
  refreshToken: string;
  expiresIn: number;
}

export interface RegisterInput {
  email: string;
  username: string;
  password: string;
}

export interface LoginInput {
  email: string;
  password: string;
}

// ============================================
// MODULE TYPES
// ============================================

export interface ModuleContent {
  introduction?: string;
  examples?: ModuleExample[];
  exercises?: ModuleExerciseSection[];
  answers?: ModuleAnswer[];
}

export interface ModuleExample {
  title: string;
  content: string;
  latexFormula?: string;
  explanation: string;
  difficulty?: ExerciseDifficulty;
}

export interface ModuleExerciseSection {
  section: string;
  content: string;
  problems: {
    id: string;
    statement: string;
    type: ExerciseType;
  }[];
}

export interface ModuleAnswer {
  exerciseId: string;
  answer: string;
  explanation: string;
  latexFormula?: string;
}

// ============================================
// TOPIC TYPES
// ============================================

export interface TheoryContent {
  concept: string;
  explanation: string;
  formulas: LatexFormula[];
  examples: ModuleExample[];
}

export interface LatexFormula {
  name: string;
  latex: string;
  description: string;
  category?: string;
}

export interface KeyPoint {
  title: string;
  explanation: string;
  latex?: string;
}

export interface CommonMistake {
  mistake: string;
  correction: string;
  explanation: string;
}

// ============================================
// EXERCISE TYPES
// ============================================

export interface ExerciseContent {
  statement: string;
  correctAnswer: string;
  solutionSteps?: SolutionStep[];
  formulas?: LatexFormula[];
  hints?: ExerciseHint[];
  multipleChoiceOptions?: MultipleChoiceOption[];
  proofRequirements?: ProofRequirements;
  calculationSteps?: CalculationStep[];
}

export interface SolutionStep {
  step: number;
  explanation: string;
  latexFormula?: string;
}

export interface ExerciseHint {
  hint: string;
  cost: number;
}

export interface MultipleChoiceOption {
  option: string;
  isCorrect: boolean;
  explanation?: string;
}

export interface ProofRequirements {
  givens: string[];
  toProve: string;
  theorems: string[];
}

export interface CalculationStep {
  step: number;
  operation: string;
  result: string;
  latexFormula?: string;
}

export interface ExerciseAttemptInput {
  answer: string;
  timeSpent: number;
  hintsUsed?: number;
  skipped?: boolean;
}

export interface ExerciseAttemptResponse {
  isCorrect: boolean;
  points: number;
  message: string;
  correctAnswer?: string;
  solutionSteps?: SolutionStep[];
}

// ============================================
// PROGRESS TYPES
// ============================================

export interface ProgressMetrics {
  exercisesCompleted: number;
  totalExercises: number;
  points: number;
  percentage: number;
  averageScore?: number;
  totalTimeSpent: number;
  perfectExercises: number;
  attemptsCount: number;
}

export interface ModuleProgress {
  moduleId: string;
  moduleName: string;
  isStarted: boolean;
  isCompleted: boolean;
  startedAt?: Date;
  completedAt?: Date;
  lastAccessedAt?: Date;
  metrics: ProgressMetrics;
}

// ============================================
// ACHIEVEMENT TYPES
// ============================================

export interface AchievementMetadata {
  color: string;
  animation?: string;
  tooltip: string;
  unlockMessage: string;
}

export interface UserAchievementProgress {
  achievementId: string;
  code: string;
  name: string;
  description: string;
  category: string;
  rarity: string;
  icon: string;
  progress: number;
  requirementValue: number;
  unlocked: boolean;
  unlockedAt?: Date;
}

// ============================================
// RANKING TYPES
// ============================================

export interface RankingEntry {
  position: number;
  points: number;
  exercisesCompleted: number;
  streak: number;
  perfectExercises: number;
  averageScore?: number;
  achievementsUnlocked: number;
}

export interface UserRankingPosition {
  global: RankingEntry;
  byModule: {
    moduleId: string;
    moduleName: string;
    position: number;
  }[];
}

// ============================================
// NOTIFICATION TYPES
// ============================================

export interface NotificationMetadata {
  userId?: string;
  relatedData?: any;
  actionUrl?: string;
}

export interface TelegramNotification {
  type: string;
  title: string;
  message: string;
  chatId: string;
  priority?: number;
  metadata?: NotificationMetadata;
}

// ============================================
// PDF PROCESSING TYPES
// ============================================

export interface ExtractedPage {
  page: number;
  text: string;
  tables?: ExtractedTable[];
  images?: ExtractedImage[];
}

export interface ExtractedTable {
  rows: string[][];
  caption?: string;
}

export interface ExtractedImage {
  position: { x: number; y: number };
  caption?: string;
}

export interface DetectedExercise {
  page: number;
  exerciseNumber: number | string;
  content: string;
  type: ExerciseType;
  formulas?: string[];
}

export interface PdfMetadata {
  author?: string;
  pages: number;
  isbn?: string;
  year?: number;
  edition?: string;
  title?: string;
}

export interface ProcessedPdfContent {
  fileName: string;
  type: string;
  topicType?: TopicType;
  pages: ExtractedPage[];
  exercisesDetected: DetectedExercise[];
  formulasExtracted: LatexFormula[];
  metadata: PdfMetadata;
}

// ============================================
// SYSTEM CONFIG TYPES
// ============================================

export interface SystemConfiguration {
  key: string;
  value: any;
  description?: string;
  category?: string;
  isPublic?: boolean;
}

// ============================================
// ERROR TYPES
// ============================================

export interface AppError extends Error {
  code: string;
  statusCode: number;
  isOperational: boolean;
  details?: any;
}

export class ApplicationError extends Error implements AppError {
  code: string;
  statusCode: number;
  isOperational: boolean;
  details?: any;

  constructor(
    message: string,
    code: string = 'INTERNAL_ERROR',
    statusCode: number = 500,
    isOperational: boolean = true,
    details?: any
  ) {
    super(message);
    this.name = 'ApplicationError';
    this.code = code;
    this.statusCode = statusCode;
    this.isOperational = isOperational;
    this.details = details;
    Error.captureStackTrace(this, this.constructor);
  }
}

export class ValidationError extends ApplicationError {
  constructor(message: string, details?: any) {
    super(message, 'VALIDATION_ERROR', 400, true, details);
    this.name = 'ValidationError';
  }
}

export class AuthenticationError extends ApplicationError {
  constructor(message: string = 'Authentication failed') {
    super(message, 'AUTHENTICATION_ERROR', 401, true);
    this.name = 'AuthenticationError';
  }
}

export class AuthorizationError extends ApplicationError {
  constructor(message: string = 'Insufficient permissions') {
    super(message, 'AUTHORIZATION_ERROR', 403, true);
    this.name = 'AuthorizationError';
  }
}

export class NotFoundError extends ApplicationError {
  constructor(resource: string) {
    super(`${resource} not found`, 'NOT_FOUND', 404, true);
    this.name = 'NotFoundError';
  }
}

export class ConflictError extends ApplicationError {
  constructor(message: string, details?: any) {
    super(message, 'CONFLICT_ERROR', 409, true, details);
    this.name = 'ConflictError';
  }
}

export class RateLimitError extends ApplicationError {
  constructor(retryAfter?: number) {
    super(
      'Too many requests',
      'RATE_LIMIT_ERROR',
      429,
      true,
      { retryAfter }
    );
    this.name = 'RateLimitError';
  }
}

// ============================================
// UTILITY TYPES
// ============================================

export type WithId<T> = T & { id: string };

export type WithTimestamps<T> = T & {
  createdAt: Date;
  updatedAt: Date;
};

export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

export type Nullable<T> = T | null;

export type Optional<T> = T | undefined;
