package com.cameleer.server.app.controller;

import com.cameleer.server.app.dto.AppSettingsRequest;
import com.cameleer.server.app.web.EnvPath;
import com.cameleer.server.core.admin.AppSettings;
import com.cameleer.server.core.admin.AppSettingsRepository;
import com.cameleer.server.core.admin.AuditCategory;
import com.cameleer.server.core.admin.AuditResult;
import com.cameleer.server.core.admin.AuditService;
import com.cameleer.server.core.runtime.Environment;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
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.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

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

@RestController
@RequestMapping("/api/v1/environments/{envSlug}")
@PreAuthorize("hasAnyRole('ADMIN', 'OPERATOR')")
@Tag(name = "App Settings", description = "Per-application dashboard settings (ADMIN/OPERATOR)")
public class AppSettingsController {

    private final AppSettingsRepository repository;
    private final AuditService auditService;

    public AppSettingsController(AppSettingsRepository repository, AuditService auditService) {
        this.repository = repository;
        this.auditService = auditService;
    }

    @GetMapping("/app-settings")
    @Operation(summary = "List application settings in this environment")
    public ResponseEntity<List<AppSettings>> getAll(@EnvPath Environment env) {
        return ResponseEntity.ok(repository.findByEnvironment(env.slug()));
    }

    @GetMapping("/apps/{appSlug}/settings")
    @Operation(summary = "Get settings for an application in this environment (returns defaults if not configured)")
    public ResponseEntity<AppSettings> getByAppId(@EnvPath Environment env,
                                                   @PathVariable String appSlug) {
        AppSettings settings = repository.findByApplicationAndEnvironment(appSlug, env.slug())
                .orElse(AppSettings.defaults(appSlug, env.slug()));
        return ResponseEntity.ok(settings);
    }

    @PutMapping("/apps/{appSlug}/settings")
    @Operation(summary = "Create or update settings for an application in this environment")
    public ResponseEntity<AppSettings> update(@EnvPath Environment env,
                                               @PathVariable String appSlug,
                                               @Valid @RequestBody AppSettingsRequest request,
                                               HttpServletRequest httpRequest) {
        List<String> errors = request.validate();
        if (!errors.isEmpty()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.join("; ", errors));
        }

        AppSettings saved = repository.save(request.toSettings(appSlug, env.slug()));
        auditService.log("update_app_settings", AuditCategory.CONFIG, appSlug,
                Map.of("environment", env.slug(), "settings", saved), AuditResult.SUCCESS, httpRequest);
        return ResponseEntity.ok(saved);
    }

    @DeleteMapping("/apps/{appSlug}/settings")
    @Operation(summary = "Delete application settings for this environment (reverts to defaults)")
    public ResponseEntity<Void> delete(@EnvPath Environment env,
                                        @PathVariable String appSlug,
                                        HttpServletRequest httpRequest) {
        repository.delete(appSlug, env.slug());
        auditService.log("delete_app_settings", AuditCategory.CONFIG, appSlug,
                Map.of("environment", env.slug()), AuditResult.SUCCESS, httpRequest);
        return ResponseEntity.noContent().build();
    }
}
