import { IRepository } from '../../../../core/interfaces/IRepository';
import { 
  PayrollEntry, 
  PayrollBatch, 
  PayrollPeriod, 
  PayrollStatus,
  PayrollSummary,
  PayrollFilter,
  PayrollRewardBreakdown
} from '../../types/payroll.types';

export interface IPayrollEntryRepository extends IRepository<PayrollEntry> {
  // Basic CRUD operations inherited from IRepository
  
  // Payroll entry-specific queries
  findByUserId(userId: string): Promise<PayrollEntry[]>;
  findByBatchId(batchId: string): Promise<PayrollEntry[]>;
  findByUserIdAndBatch(userId: string, batchId: string): Promise<PayrollEntry | null>;
  
  findByUserIdAndPeriod(
    userId: string, 
    startDate: Date, 
    endDate: Date
  ): Promise<PayrollEntry[]>;
  
  // Batch operations
  createBatch(
    entries: Omit<PayrollEntry, 'id' | 'createdAt' | 'updatedAt'>[]
  ): Promise<PayrollEntry[]>;
  
  updateStatusBatch(
    entryIds: string[], 
    status: PayrollStatus
  ): Promise<void>;
  
  // Statistics and reporting
  getUserPayrollSummary(
    userId: string, 
    year?: number
  ): Promise<{
    totalEarnings: number;
    totalEntries: number;
    averageEarnings: number;
    earningsByMonth: Record<string, number>;
  }>;
  
  getPayrollTrends(
    startDate: Date, 
    endDate: Date, 
    groupBy: 'day' | 'week' | 'month'
  ): Promise<Array<{
    period: string;
    totalEntries: number;
    totalAmount: number;
    uniqueUsers: number;
    averagePerUser: number;
  }>>;
}

export interface IPayrollBatchRepository extends IRepository<PayrollBatch> {
  // Batch-specific queries
  findByPeriod(period: PayrollPeriod): Promise<PayrollBatch[]>;
  findByStatus(status: PayrollStatus): Promise<PayrollBatch[]>;
  findByDateRange(startDate: Date, endDate: Date): Promise<PayrollBatch[]>;
  
  findCurrentBatch(): Promise<PayrollBatch | null>;
  findLatestBatch(): Promise<PayrollBatch | null>;
  
  // Batch operations
  updateBatchStatus(
    batchId: string, 
    status: PayrollStatus,
    processedAt?: Date,
    processedBy?: string
  ): Promise<PayrollBatch>;
  
  // Batch statistics
  getBatchSummary(batchId: string): Promise<PayrollSummary>;
  
  getBatchStatistics(batchId: string): Promise<{
    totalEntries: number;
    totalAmount: number;
    uniqueUsers: number;
    averagePerUser: number;
    rewardBreakdown: PayrollRewardBreakdown;
    statusDistribution: Record<PayrollStatus, number>;
  }>;
  
  // Validation and integrity
  validateBatchIntegrity(batchId: string): Promise<{
    isValid: boolean;
    issues: string[];
    totalCalculated: number;
    totalRecorded: number;
  }>;
  
  // Audit and compliance
  getBatchAuditTrail(batchId: string): Promise<Array<{
    timestamp: Date;
    action: string;
    performedBy: string;
    details: Record<string, any>;
  }>>;
  
  // Reporting
  generatePayrollReport(
    batchId: string, 
    format: 'summary' | 'detailed' | 'export'
  ): Promise<{
    reportData: any;
    generatedAt: Date;
    totalRecords: number;
  }>;
  
  // Scheduled payroll
  findScheduledBatches(dueDate: Date): Promise<PayrollBatch[]>;
  
  // Comparison and analysis
  compareBatches(
    batchId1: string, 
    batchId2: string
  ): Promise<{
    batch1Summary: PayrollSummary;
    batch2Summary: PayrollSummary;
    differences: {
      totalAmountDiff: number;
      entryCountDiff: number;
      userCountDiff: number;
    };
  }>;
  
  // Export and import
  exportBatchData(
    batchId: string, 
    format: 'csv' | 'excel' | 'json'
  ): Promise<{
    data: any;
    filename: string;
    mimeType: string;
  }>;
  
  // Calendar and scheduling
  getPayrollCalendar(
    year: number, 
    period: PayrollPeriod
  ): Promise<Array<{
    periodStart: Date;
    periodEnd: Date;
    payrollDate: Date;
    isHoliday: boolean;
    adjustedPayrollDate?: Date;
  }>>;
}