// Core Types
export interface CrawlerConfig {
  maxDepth: number;
  maxPages: number;
  respectRobots: boolean;
  rateLimit: number;
  userAgent: string;
  timeout: number;
}

export interface PageInfo {
  url: string;
  title: string;
  depth: number;
  links: string[];
  assets: AssetInfo[];
  metadata: PageMetadata;
}

export interface AssetInfo {
  url: string;
  type: 'image' | 'css' | 'js' | 'font' | 'media';
  size: number;
  hash: string;
  dependencies: string[];
}

export interface PageMetadata {
  description?: string;
  keywords?: string[];
  author?: string;
  viewport?: string;
  charset?: string;
  language?: string;
}

// Visual Scraping Types
export interface Viewport {
  width: number;
  height: number;
  deviceScaleFactor: number;
  isMobile: boolean;
}

export interface Screenshot {
  viewport: Viewport;
  data: Buffer;
  format: 'png' | 'jpeg' | 'webp';
  quality: number;
}

export interface VisualData {
  screenshots: Screenshot[];
  computedStyles: Record<string, Record<string, string>>;
  layoutMetrics: LayoutMetrics;
  animations: AnimationInfo[];
}

export interface LayoutMetrics {
  width: number;
  height: number;
  scrollWidth: number;
  scrollHeight: number;
  elements: ElementMetrics[];
}

export interface ElementMetrics {
  selector: string;
  boundingBox: BoundingBox;
  styles: Record<string, string>;
  isVisible: boolean;
}

export interface BoundingBox {
  x: number;
  y: number;
  width: number;
  height: number;
}

export interface AnimationInfo {
  selector: string;
  property: string;
  duration: number;
  timing: string;
  delay: number;
}

// Code Generation Types
export interface GenerationConfig {
  framework: 'vanilla' | 'react' | 'vue' | 'angular';
  cssFramework: 'none' | 'tailwind' | 'bootstrap';
  optimization: 'none' | 'basic' | 'aggressive';
  accessibility: boolean;
  responsive: boolean;
}

export interface GeneratedCode {
  html: string;
  css: string;
  javascript: string;
  components: ComponentDefinition[];
  assets: AssetMapping[];
}

export interface ComponentDefinition {
  id: string;
  name: string;
  type: ComponentType;
  html: string;
  css: string;
  javascript?: string;
  props: ComponentProp[];
  instances: ComponentInstance[];
}

export interface ComponentProp {
  name: string;
  type: 'string' | 'number' | 'boolean' | 'object';
  required: boolean;
  defaultValue?: any;
}

export interface ComponentInstance {
  id: string;
  selector: string;
  props: Record<string, any>;
}

export interface AssetMapping {
  originalUrl: string;
  localPath: string;
  optimized: boolean;
  size: number;
}

// Component Detection Types
export interface ComponentPattern {
  type: ComponentType;
  selector: string;
  frequency: number;
  variations: ComponentVariation[];
  confidence: number;
}

export interface ComponentVariation {
  html: string;
  css: string;
  props: Record<string, any>;
}

export type ComponentType = 
  | 'navigation' 
  | 'header' 
  | 'footer' 
  | 'card' 
  | 'form' 
  | 'button' 
  | 'modal'
  | 'sidebar'
  | 'hero'
  | 'gallery'
  | 'other';

// Site Structure Types
export interface SiteMap {
  rootUrl: string;
  pages: PageInfo[];
  assets: AssetInfo[];
  structure: SiteStructure;
  metadata: SiteMetadata;
}

export interface SiteStructure {
  hierarchy: PageHierarchy[];
  navigation: NavigationStructure[];
  breadcrumbs: BreadcrumbStructure[];
}

export interface PageHierarchy {
  url: string;
  level: number;
  parent?: string;
  children: string[];
}

export interface NavigationStructure {
  type: 'main' | 'footer' | 'sidebar' | 'breadcrumb';
  items: NavigationItem[];
}

export interface NavigationItem {
  text: string;
  url: string;
  children?: NavigationItem[];
}

export interface BreadcrumbStructure {
  page: string;
  breadcrumbs: NavigationItem[];
}

export interface SiteMetadata {
  title: string;
  description?: string;
  language: string;
  favicon?: string;
  robots?: string;
  sitemap?: string;
}

// API Types
export interface ApiResponse<T = any> {
  success: boolean;
  data?: T;
  error?: string;
  message?: string;
}

export interface PaginatedResponse<T> extends ApiResponse<T[]> {
  pagination: {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
  };
}

// Job Queue Types
export interface CrawlJob {
  projectId: string;
  startUrl: string;
  config: CrawlerConfig;
}

export interface ScrapeJob {
  projectId: string;
  pageId: string;
  url: string;
  config: ScreenshotConfig;
}

export interface GenerateJob {
  projectId: string;
  visualData: VisualData;
  config: GenerationConfig;
}

export interface ScreenshotConfig {
  viewports: Viewport[];
  fullPage: boolean;
  quality: number;
  format: 'png' | 'jpeg' | 'webp';
}

// User and Project Types
export interface UserProfile {
  id: string;
  email: string;
  firstName?: string;
  lastName?: string;
  avatar?: string;
  subscription: SubscriptionTier;
  usage: UsageMetrics;
}

export interface UsageMetrics {
  pagesCloned: number;
  storageUsed: number;
  apiCalls: number;
  lastReset: Date;
}

export type SubscriptionTier = 'FREE' | 'BASIC' | 'PRO' | 'ENTERPRISE';

export interface ProjectSettings {
  crawlerConfig: CrawlerConfig;
  generationConfig: GenerationConfig;
  notifications: NotificationSettings;
}

export interface NotificationSettings {
  email: boolean;
  webhook?: string;
  slack?: string;
}

// Error Types
export class CloneWebError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number = 500
  ) {
    super(message);
    this.name = 'CloneWebError';
  }
}

export class ValidationError extends CloneWebError {
  constructor(message: string, public field?: string) {
    super(message, 'VALIDATION_ERROR', 400);
    this.name = 'ValidationError';
  }
}

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

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

export class RateLimitError extends CloneWebError {
  constructor(message: string = 'Rate limit exceeded') {
    super(message, 'RATE_LIMIT_ERROR', 429);
    this.name = 'RateLimitError';
  }
}