package com.yimeng.okr.service;

import com.yimeng.okr.exception.BusinessException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class DatabaseBackupService {

    private final String datasourceUrl;
    private final String backupDir;

    public DatabaseBackupService(
            @Value("${spring.datasource.url}") String datasourceUrl,
            @Value("${app.backup.dir:./data/backups}") String backupDir) {
        this.datasourceUrl = datasourceUrl;
        this.backupDir = backupDir;
    }

    public Path createBackup() {
        return createBackup("okr-performance");
    }

    public Path createBackup(String label) {
        Path dbPath;
        try {
            dbPath = resolveSqlitePath(datasourceUrl);
        } catch (Exception e) {
            // In-memory or non-file databases — skip backup
            return null;
        }
        if (!Files.exists(dbPath) || !Files.isRegularFile(dbPath)) {
            // In-memory or non-existent — skip backup silently
            return null;
        }
        try {
            Files.createDirectories(Path.of(backupDir));
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss"));
            String safeLabel = label.replaceAll("[^a-zA-Z0-9\\-_.]", "-");
            Path target = Path.of(backupDir).resolve(safeLabel + "-" + timestamp + ".db");
            Files.copy(dbPath, target);
            return target;
        } catch (IOException e) {
            throw new BusinessException("数据库备份失败: " + e.getMessage());
        }
    }

    private Path resolveSqlitePath(String url) {
        if (url == null || !url.startsWith("jdbc:sqlite:")) {
            throw new BusinessException("仅支持 jdbc:sqlite 数据库备份");
        }
        String path = url.substring("jdbc:sqlite:".length());
        // Strip query parameters
        int queryIdx = path.indexOf('?');
        if (queryIdx >= 0) {
            path = path.substring(0, queryIdx);
        }
        // Handle file: prefix for shared cache mode
        if (path.startsWith("file:")) {
            path = path.substring(5);
        }
        // :memory: is not a file
        if (path.contains(":memory:")) {
            throw new BusinessException("内存数据库，无需备份");
        }
        return Path.of(path).normalize();
    }
}
