import type { Result as AxeResult, ImpactValue, TagValue } from 'axe-core';

export interface WCAGLevel {
  level: 'A' | 'AA' | 'AAA';
  version: '2.0' | '2.1' | '2.2';
}

export interface AccessibilityScanOptions {
  url: string;
  wcagLevel?: WCAGLevel;
  viewport?: ViewportSize;
  authenticate?: AuthenticationConfig;
  includeScreenshots?: boolean;
  customRules?: CustomRule[];
  scanSubpages?: boolean;
  maxDepth?: number;
  timeout?: number;
  waitForSelector?: string;
  excludeSelectors?: string[];
}

export interface ViewportSize {
  width: number;
  height: number;
  deviceScaleFactor?: number;
  isMobile?: boolean;
}

export interface AuthenticationConfig {
  type: 'basic' | 'form' | 'oauth' | 'custom';
  credentials?: {
    username?: string;
    password?: string;
    token?: string;
  };
  loginUrl?: string;
  selectors?: {
    username?: string;
    password?: string;
    submit?: string;
  };
  customScript?: string;
}

export interface CustomRule {
  id: string;
  selector: string;
  tags: string[];
  description: string;
  help: string;
  helpUrl?: string;
  severity: ImpactValue;
  validator: (element: Element) => boolean | Promise<boolean>;
}

export interface AccessibilityViolation {
  id: string;
  impact: ImpactValue;
  description: string;
  help: string;
  helpUrl: string;
  tags: TagValue[];
  nodes: ViolationNode[];
  wcagCriteria?: string[];
  fixSuggestion?: string;
}

export interface ViolationNode {
  html: string;
  target: string[];
  xpath?: string;
  failureSummary?: string;
  screenshot?: string;
  relatedNodes?: RelatedNode[];
}

export interface RelatedNode {
  html: string;
  target: string[];
}

export interface AccessibilityScanResult {
  url: string;
  timestamp: Date;
  scanDuration: number;
  summary: ScanSummary;
  violations: AccessibilityViolation[];
  passes: AxeResult[];
  incomplete: AxeResult[];
  inapplicable: AxeResult[];
  pageMetadata: PageMetadata;
  wcagCompliance: WCAGCompliance;
}

export interface ScanSummary {
  violationCount: number;
  passCount: number;
  incompleteCount: number;
  inapplicableCount: number;
  criticalIssues: number;
  seriousIssues: number;
  moderateIssues: number;
  minorIssues: number;
  score: number;
}

export interface PageMetadata {
  title: string;
  url: string;
  viewport: ViewportSize;
  language?: string;
  doctype?: string;
  hasLandmarks: boolean;
  hasHeadings: boolean;
  imagesCount: number;
  formsCount: number;
  linksCount: number;
}

export interface WCAGCompliance {
  level: WCAGLevel;
  isCompliant: boolean;
  criteriaResults: CriteriaResult[];
  overallScore: number;
}

export interface CriteriaResult {
  criterion: string;
  level: 'A' | 'AA' | 'AAA';
  passed: boolean;
  violations: string[];
}

export interface ScanJob {
  id: string;
  websiteId: string;
  url: string;
  status: 'pending' | 'running' | 'completed' | 'failed';
  options: AccessibilityScanOptions;
  scheduledAt: Date;
  startedAt?: Date;
  completedAt?: Date;
  error?: string;
  resultId?: string;
  retryCount: number;
}

export interface Website {
  id: string;
  name: string;
  url: string;
  userId: string;
  scanSchedule?: ScanSchedule;
  lastScanAt?: Date;
  complianceScore?: number;
  tags?: string[];
  active: boolean;
  createdAt: Date;
  updatedAt: Date;
}

export interface ScanSchedule {
  frequency: 'manual' | 'hourly' | 'daily' | 'weekly' | 'monthly';
  dayOfWeek?: number;
  dayOfMonth?: number;
  hour?: number;
  timezone?: string;
}

export interface ComplianceReport {
  id: string;
  websiteId: string;
  period: ReportPeriod;
  generatedAt: Date;
  summary: ReportSummary;
  trendsData: TrendData[];
  detailedResults: AccessibilityScanResult[];
  recommendations: string[];
  format: 'pdf' | 'html' | 'json' | 'csv';
}

export interface ReportPeriod {
  start: Date;
  end: Date;
}

export interface ReportSummary {
  averageScore: number;
  totalScans: number;
  improvementRate: number;
  criticalIssuesFixed: number;
  newIssuesFound: number;
  complianceLevel: WCAGLevel;
}

export interface TrendData {
  date: Date;
  score: number;
  violationCount: number;
  passCount: number;
}