package com.erp.systemtool.service;

import com.erp.systemtool.repository.OperationLogRepository;
import com.erp.systemtool.repository.AuditLogRepository;
import com.erp.systemtool.repository.PullRecordRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * Data Cleanup Service
 * 
 * Provides scheduled and manual data cleanup operations.
 * Migrations from PHP CleanPullRecordsCommand and related cleanup logic.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DataCleanupService {

    private final OperationLogRepository operationLogRepository;
    private final AuditLogRepository auditLogRepository;
    private final PullRecordRepository pullRecordRepository;
    private final JdbcTemplate jdbcTemplate;

    /**
     * Cleanup old pull records (runs daily at 2 AM)
     * Migrations from PHP CleanPullRecordsCommand
     */
    @Scheduled(cron = "0 0 2 * * ?")
    @Transactional
    public Map<String, Object> cleanupOldPullRecords() {
        return cleanupOldPullRecords(30);
    }

    /**
     * Cleanup old pull records with specified retention days
     */
    @Transactional
    public Map<String, Object> cleanupOldPullRecords(int retentionDays) {
        LocalDateTime cutoffDate = LocalDateTime.now().minusDays(retentionDays);
        long deletedCount = pullRecordRepository.deleteOlderThan(cutoffDate);
        
        Map<String, Object> result = new HashMap<>();
        result.put("type", "pull_records");
        result.put("deleted_count", deletedCount);
        result.put("retention_days", retentionDays);
        result.put("cutoff_date", cutoffDate.toString());
        
        log.info("Cleaned up {} old pull records older than {} days", deletedCount, retentionDays);
        return result;
    }

    /**
     * Cleanup old operation logs (runs daily at 3 AM)
     */
    @Scheduled(cron = "0 0 3 * * ?")
    @Transactional
    public Map<String, Object> cleanupOldOperationLogs() {
        return cleanupOldOperationLogs(90);
    }

    /**
     * Cleanup old operation logs with specified retention days
     */
    @Transactional
    public Map<String, Object> cleanupOldOperationLogs(int retentionDays) {
        LocalDateTime cutoffDate = LocalDateTime.now().minusDays(retentionDays);
        long deletedCount = operationLogRepository.deleteOlderThan(cutoffDate);
        
        Map<String, Object> result = new HashMap<>();
        result.put("type", "operation_logs");
        result.put("deleted_count", deletedCount);
        result.put("retention_days", retentionDays);
        result.put("cutoff_date", cutoffDate.toString());
        
        log.info("Cleaned up {} old operation logs older than {} days", deletedCount, retentionDays);
        return result;
    }

    /**
     * Cleanup old audit logs (runs daily at 4 AM)
     */
    @Scheduled(cron = "0 0 4 * * ?")
    @Transactional
    public Map<String, Object> cleanupOldAuditLogs() {
        return cleanupOldAuditLogs(180);
    }

    /**
     * Cleanup old audit logs with specified retention days
     */
    @Transactional
    public Map<String, Object> cleanupOldAuditLogs(int retentionDays) {
        LocalDateTime cutoffDate = LocalDateTime.now().minusDays(retentionDays);
        long deletedCount = auditLogRepository.deleteOlderThan(cutoffDate);
        
        Map<String, Object> result = new HashMap<>();
        result.put("type", "audit_logs");
        result.put("deleted_count", deletedCount);
        result.put("retention_days", retentionDays);
        result.put("cutoff_date", cutoffDate.toString());
        
        log.info("Cleaned up {} old audit logs older than {} days", deletedCount, retentionDays);
        return result;
    }

    /**
     * Execute full cleanup of all old data
     */
    @Transactional
    public Map<String, Object> fullCleanup(Map<String, Integer> retentionDays) {
        Map<String, Object> results = new HashMap<>();

        results.put("pull_records", cleanupOldPullRecords(
            retentionDays.getOrDefault("pull_records", 30)));
        results.put("operation_logs", cleanupOldOperationLogs(
            retentionDays.getOrDefault("operation_logs", 90)));
        results.put("audit_logs", cleanupOldAuditLogs(
            retentionDays.getOrDefault("audit_logs", 180)));

        return results;
    }

    /**
     * Get cleanup status and statistics
     */
    public Map<String, Object> getCleanupStatus() {
        Map<String, Object> status = new HashMap<>();
        
        // Count records older than retention periods
        LocalDateTime pullCutoff = LocalDateTime.now().minusDays(30);
        LocalDateTime opLogCutoff = LocalDateTime.now().minusDays(90);
        LocalDateTime auditCutoff = LocalDateTime.now().minusDays(180);

        status.put("pull_records", Map.of(
            "total_count", pullRecordRepository.count(),
            "old_count", pullRecordRepository.countByCreatedAtBefore(pullCutoff),
            "retention_days", 30
        ));
        
        status.put("operation_logs", Map.of(
            "retention_days", 90
        ));
        
        status.put("audit_logs", Map.of(
            "retention_days", 180
        ));

        return status;
    }
}
