package com.storycove.controller;

import com.storycove.dto.LibraryDto;
import com.storycove.service.LibraryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/libraries")
public class LibraryController {
    
    private static final Logger logger = LoggerFactory.getLogger(LibraryController.class);
    
    private final LibraryService libraryService;
    
    @Autowired
    public LibraryController(LibraryService libraryService) {
        this.libraryService = libraryService;
    }
    
    /**
     * Get all available libraries (for settings UI)
     */
    @GetMapping
    public ResponseEntity<List<LibraryDto>> getAllLibraries() {
        try {
            List<LibraryDto> libraries = libraryService.getAllLibraries();
            return ResponseEntity.ok(libraries);
        } catch (Exception e) {
            logger.error("Failed to get libraries", e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * Get current active library info
     */
    @GetMapping("/current")
    public ResponseEntity<LibraryDto> getCurrentLibrary() {
        try {
            var library = libraryService.getCurrentLibrary();
            if (library == null) {
                return ResponseEntity.noContent().build();
            }
            
            LibraryDto dto = new LibraryDto(
                library.getId(),
                library.getName(), 
                library.getDescription(),
                true, // always active since it's current
                library.isInitialized()
            );
            
            return ResponseEntity.ok(dto);
        } catch (Exception e) {
            logger.error("Failed to get current library", e);
            return ResponseEntity.internalServerError().build();
        }
    }
    
    /**
     * Switch to a different library (requires re-authentication)
     * This endpoint returns a switching status that the frontend can poll
     */
    @PostMapping("/switch")
    public ResponseEntity<Map<String, Object>> initiateLibrarySwitch(@RequestBody Map<String, String> request) {
        try {
            String password = request.get("password");
            if (password == null || password.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "Password required"));
            }
            
            String libraryId = libraryService.authenticateAndGetLibrary(password);
            if (libraryId == null) {
                return ResponseEntity.status(401).body(Map.of("error", "Invalid password"));
            }
            
            // Check if already on this library
            if (libraryId.equals(libraryService.getCurrentLibraryId())) {
                return ResponseEntity.ok(Map.of(
                    "status", "already_active",
                    "message", "Already using this library"
                ));
            }
            
            // Initiate switch in background thread
            new Thread(() -> {
                try {
                    libraryService.switchToLibrary(libraryId);
                    logger.info("Library switch completed: {}", libraryId);
                } catch (Exception e) {
                    logger.error("Library switch failed: {}", libraryId, e);
                }
            }).start();
            
            return ResponseEntity.ok(Map.of(
                "status", "switching",
                "targetLibrary", libraryId,
                "message", "Switching to library, please wait..."
            ));
            
        } catch (Exception e) {
            logger.error("Failed to initiate library switch", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "Server error"));
        }
    }
    
    /**
     * Check library switch status
     */
    @GetMapping("/switch/status")
    public ResponseEntity<Map<String, Object>> getLibrarySwitchStatus() {
        try {
            var currentLibrary = libraryService.getCurrentLibrary();
            boolean isReady = currentLibrary != null;
            
            Map<String, Object> response = new HashMap<>();
            response.put("ready", isReady);
            if (isReady) {
                response.put("currentLibrary", currentLibrary.getId());
                response.put("currentLibraryName", currentLibrary.getName());
            } else {
                response.put("currentLibrary", null);
                response.put("currentLibraryName", null);
            }
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("Failed to get switch status", e);
            return ResponseEntity.ok(Map.of("ready", false, "error", "Status check failed"));
        }
    }
    
    /**
     * Change password for current library
     */
    @PostMapping("/password")
    public ResponseEntity<Map<String, Object>> changePassword(@RequestBody Map<String, String> request) {
        try {
            String currentPassword = request.get("currentPassword");
            String newPassword = request.get("newPassword");
            
            if (currentPassword == null || newPassword == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "Current and new passwords required"));
            }
            
            String currentLibraryId = libraryService.getCurrentLibraryId();
            if (currentLibraryId == null) {
                return ResponseEntity.badRequest().body(Map.of("error", "No active library"));
            }
            
            boolean success = libraryService.changeLibraryPassword(currentLibraryId, currentPassword, newPassword);
            if (success) {
                return ResponseEntity.ok(Map.of("success", true, "message", "Password changed successfully"));
            } else {
                return ResponseEntity.badRequest().body(Map.of("error", "Current password is incorrect"));
            }
            
        } catch (Exception e) {
            logger.error("Failed to change password", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "Server error"));
        }
    }
    
    /**
     * Create a new library
     */
    @PostMapping("/create")
    public ResponseEntity<Map<String, Object>> createLibrary(@RequestBody Map<String, String> request) {
        try {
            String name = request.get("name");
            String description = request.get("description");
            String password = request.get("password");
            
            if (name == null || name.trim().isEmpty() || password == null || password.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "Name and password are required"));
            }
            
            var newLibrary = libraryService.createNewLibrary(name.trim(), description, password);
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "library", Map.of(
                    "id", newLibrary.getId(),
                    "name", newLibrary.getName(),
                    "description", newLibrary.getDescription()
                ),
                "message", "Library created successfully. You can now log in with the new password to access it."
            ));
            
        } catch (Exception e) {
            logger.error("Failed to create library", e);
            return ResponseEntity.internalServerError().body(Map.of("error", "Server error"));
        }
    }
    
    /**
     * Update library metadata (name and description)
     */
    @PutMapping("/{libraryId}/metadata")
    public ResponseEntity<Map<String, Object>> updateLibraryMetadata(
            @PathVariable String libraryId,
            @RequestBody Map<String, String> updates) {
        
        try {
            String newName = updates.get("name");
            String newDescription = updates.get("description");
            
            if (newName == null || newName.trim().isEmpty()) {
                return ResponseEntity.badRequest().body(Map.of("error", "Library name is required"));
            }
            
            // Update the library
            libraryService.updateLibraryMetadata(libraryId, newName, newDescription);
            
            // Return updated library info
            LibraryDto updatedLibrary = libraryService.getLibraryById(libraryId);
            if (updatedLibrary != null) {
                Map<String, Object> response = new HashMap<>();
                response.put("success", true);
                response.put("message", "Library metadata updated successfully");
                response.put("library", updatedLibrary);
                return ResponseEntity.ok(response);
            } else {
                return ResponseEntity.notFound().build();
            }
            
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        } catch (Exception e) {
            logger.error("Failed to update library metadata for {}: {}", libraryId, e.getMessage(), e);
            return ResponseEntity.internalServerError().body(Map.of("error", "Failed to update library metadata"));
        }
    }
}