package com.storycove.controller;

import com.storycove.service.AsyncBackupService;
import com.storycove.service.BackupManagementService;
import com.storycove.service.DatabaseManagementService;
import com.storycove.service.LibraryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/database")
public class DatabaseController {

    @Autowired
    private DatabaseManagementService databaseManagementService;

    @Autowired
    private AsyncBackupService asyncBackupService;

    @Autowired
    private BackupManagementService backupManagementService;

    @Autowired
    private LibraryService libraryService;

    // -------------------------------------------------------------------------
    // Backup creation (async, with progress polling)
    // -------------------------------------------------------------------------

    @PostMapping("/backup-complete")
    public ResponseEntity<Map<String, Object>> backupCompleteAsync() {
        try {
            String libraryId = libraryService.getCurrentLibraryId();
            if (libraryId == null) {
                return ResponseEntity.badRequest()
                        .body(Map.of("success", false, "message", "No library selected"));
            }

            com.storycove.entity.BackupJob job = asyncBackupService.startBackupJob(
                    libraryId,
                    com.storycove.entity.BackupJob.BackupType.COMPLETE
            );

            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "Backup started",
                    "jobId", job.getId().toString(),
                    "status", job.getStatus().toString()
            ));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Failed to start backup: " + e.getMessage()));
        }
    }

    @GetMapping("/backup-status/{jobId}")
    public ResponseEntity<Map<String, Object>> getBackupStatus(@PathVariable String jobId) {
        try {
            java.util.UUID uuid = java.util.UUID.fromString(jobId);
            java.util.Optional<com.storycove.entity.BackupJob> jobOpt = asyncBackupService.getJobStatus(uuid);

            if (jobOpt.isEmpty()) {
                return ResponseEntity.notFound().build();
            }

            com.storycove.entity.BackupJob job = jobOpt.get();

            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "jobId", job.getId().toString(),
                    "status", job.getStatus().toString(),
                    "progress", job.getProgressPercent(),
                    "fileSizeBytes", job.getFileSizeBytes() != null ? job.getFileSizeBytes() : 0,
                    "createdAt", job.getCreatedAt().toString(),
                    "completedAt", job.getCompletedAt() != null ? job.getCompletedAt().toString() : "",
                    "errorMessage", job.getErrorMessage() != null ? job.getErrorMessage() : ""
            ));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest()
                    .body(Map.of("success", false, "message", "Invalid job ID"));
        }
    }

    // -------------------------------------------------------------------------
    // Backup file management (filesystem-based)
    // -------------------------------------------------------------------------

    @GetMapping("/backups")
    public ResponseEntity<Map<String, Object>> listBackups() {
        try {
            List<BackupManagementService.BackupFileInfo> backups = backupManagementService.listBackups();

            List<Map<String, Object>> backupList = backups.stream()
                    .map(b -> {
                        Map<String, Object> m = new java.util.HashMap<>();
                        m.put("filename", b.getFilename());
                        m.put("sizeBytes", b.getSizeBytes());
                        m.put("createdAt", b.getCreatedAt().toString());
                        m.put("origin", b.getOrigin().toString());
                        return m;
                    })
                    .collect(Collectors.toList());

            return ResponseEntity.ok(Map.of("success", true, "backups", backupList));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Failed to list backups: " + e.getMessage()));
        }
    }

    @PostMapping("/backups/{filename}/restore")
    public ResponseEntity<Map<String, Object>> restoreFromFile(@PathVariable String filename) {
        try {
            backupManagementService.restoreFromFile(filename);
            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "Restored successfully from " + filename
            ));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Restore failed: " + e.getMessage()));
        }
    }

    @GetMapping("/backups/{filename}/download")
    public ResponseEntity<Resource> downloadBackupFile(@PathVariable String filename) {
        try {
            Resource resource = backupManagementService.getBackupResource(filename);
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"")
                    .header(HttpHeaders.CONTENT_TYPE, "application/zip")
                    .body(resource);
        } catch (Exception e) {
            return ResponseEntity.internalServerError().build();
        }
    }

    @DeleteMapping("/backups/{filename}")
    public ResponseEntity<Map<String, Object>> deleteBackupFile(@PathVariable String filename) {
        try {
            backupManagementService.deleteBackup(filename);
            return ResponseEntity.ok(Map.of("success", true, "message", "Backup deleted"));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Failed to delete backup: " + e.getMessage()));
        }
    }

    // -------------------------------------------------------------------------
    // Clear operations
    // -------------------------------------------------------------------------

    @PostMapping("/clear-complete")
    public ResponseEntity<Map<String, Object>> clearComplete() {
        try {
            int deletedRecords = databaseManagementService.clearAllDataAndFiles();
            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "Database and files cleared successfully",
                    "deletedRecords", deletedRecords
            ));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Failed to clear database and files: " + e.getMessage()));
        }
    }

    @PostMapping("/clear")
    public ResponseEntity<Map<String, Object>> clearDatabase() {
        try {
            int deletedRecords = databaseManagementService.clearAllData();
            return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "Database cleared successfully",
                    "deletedRecords", deletedRecords
            ));
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                    .body(Map.of("success", false, "message", "Failed to clear database: " + e.getMessage()));
        }
    }
}
