package net.siegeln.cameleer.saas.vendor;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api/vendor/email-connector")
@PreAuthorize("hasAuthority('SCOPE_platform:admin')")
public class EmailConnectorController {

    private final EmailConnectorService emailConnectorService;

    public EmailConnectorController(EmailConnectorService emailConnectorService) {
        this.emailConnectorService = emailConnectorService;
    }

    // --- Request/Response types ---

    public record SmtpConfigRequest(
        @NotBlank String host,
        @Min(1) @Max(65535) int port,
        @NotBlank String username,
        @NotBlank String password,
        @NotBlank @Email String fromEmail,
        Boolean registrationEnabled
    ) {}

    public record TestEmailRequest(
        @NotBlank @Email String to
    ) {}

    public record EmailConnectorResponse(
        String connectorId,
        String factoryId,
        String host,
        int port,
        String username,
        String fromEmail,
        boolean registrationEnabled
    ) {
        static EmailConnectorResponse from(EmailConnectorService.EmailConnectorStatus status) {
            return new EmailConnectorResponse(
                status.connectorId(),
                status.factoryId(),
                status.host(),
                status.port(),
                status.username(),
                status.fromEmail(),
                status.registrationEnabled()
            );
        }
    }

    // --- Endpoints ---

    @GetMapping
    public ResponseEntity<EmailConnectorResponse> get() {
        var status = emailConnectorService.getEmailConnector();
        if (status == null) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(EmailConnectorResponse.from(status));
    }

    @PostMapping
    public ResponseEntity<EmailConnectorResponse> save(@Valid @RequestBody SmtpConfigRequest request) {
        var smtp = new EmailConnectorService.SmtpConfig(
            request.host(), request.port(), request.username(),
            request.password(), request.fromEmail()
        );
        var status = emailConnectorService.saveSmtpConnector(smtp, request.registrationEnabled());
        return ResponseEntity.ok(EmailConnectorResponse.from(status));
    }

    @DeleteMapping
    public ResponseEntity<Void> delete() {
        emailConnectorService.deleteEmailConnector();
        return ResponseEntity.noContent().build();
    }

    @PostMapping("/test")
    public ResponseEntity<Map<String, String>> test(@Valid @RequestBody TestEmailRequest request) {
        try {
            emailConnectorService.sendTestEmail(request.to());
            return ResponseEntity.ok(Map.of("status", "sent", "message", "Test email sent to " + request.to()));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of("status", "failed", "message", e.getMessage()));
        }
    }

    @PostMapping("/registration")
    public ResponseEntity<Void> toggleRegistration(@RequestBody Map<String, Boolean> body) {
        boolean enabled = body.getOrDefault("enabled", false);
        var existing = emailConnectorService.getEmailConnector();
        if (existing == null && enabled) {
            return ResponseEntity.badRequest().build();
        }
        emailConnectorService.setRegistrationEnabled(enabled);
        return ResponseEntity.noContent().build();
    }
}
