package de.votian.services.controller;

import de.votian.services.entity.Parameter;
import de.votian.services.service.ParameterService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/api/parameters")
public class ParameterController {

    private final ParameterService parameterService;

    public ParameterController(ParameterService parameterService) {
        this.parameterService = parameterService;
    }

    /**
     * Get a single parameter value with PHP-compatible fallback logic.
     * Equivalent to PHP getParameterValue($empId, $key, $hqId).
     */
    @GetMapping("/value")
    public ResponseEntity<String> getValue(@RequestParam String key,
                                           @RequestParam Long hqId,
                                           @RequestParam(required = false, defaultValue = "0") Long empId) {
        String value = parameterService.getParameterValue(empId, key, hqId);
        if (value.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(value);
    }

    /**
     * Get a parameter value with automatic fallback to global (hq_id=0).
     * Equivalent to the common PHP pattern:
     *   $val = getParameterValue("0", "KEY", $hq_id);
     *   if ($val == "") : $val = getParameterValue("0", "KEY", "0"); endif;
     */
    @GetMapping("/value-with-fallback")
    public ResponseEntity<String> getValueWithFallback(@RequestParam String key,
                                                       @RequestParam Long hqId) {
        String value = parameterService.getParameterValueWithFallback(key, hqId);
        if (value.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(value);
    }

    /**
     * Get a parameter value with full fallback chain: emp+hq -> emp+0 -> 0+hq -> 0+0.
     */
    @GetMapping("/value-full-fallback")
    public ResponseEntity<String> getValueFullFallback(@RequestParam String key,
                                                       @RequestParam Long hqId,
                                                       @RequestParam(required = false, defaultValue = "0") Long empId) {
        String value = parameterService.getParameterValueFullFallback(empId, key, hqId);
        if (value.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(value);
    }

    /**
     * Get an object-based parameter value with cascading fallback.
     * Equivalent to PHP getObjectBasedParameterValue().
     */
    @GetMapping("/value-object-based")
    public ResponseEntity<String> getObjectBasedValue(@RequestParam String key,
                                                      @RequestParam(required = false) Long objId,
                                                      @RequestParam Long hqId,
                                                      @RequestParam(required = false, defaultValue = "0") Long empId,
                                                      @RequestParam(required = false, defaultValue = "false") boolean noGlobalCheck) {
        String value = parameterService.getObjectBasedParameterValue(key, objId, hqId, empId, noGlobalCheck);
        if (value.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(value);
    }

    /**
     * Bulk-load all parameters for a headquarters and employee.
     * Equivalent to PHP defineGlobalParameters() but also includes employee-specific overrides.
     * Returns a map of key -> value.
     */
    @GetMapping("/bulk")
    public ResponseEntity<Map<String, String>> bulkLoad(@RequestParam Long hqId,
                                                        @RequestParam(required = false, defaultValue = "0") Long empId) {
        Map<String, String> params = parameterService.loadAllParameters(hqId, empId);
        return ResponseEntity.ok(params);
    }

    /**
     * Get all parameter entries by key (across all headquarters).
     */
    @GetMapping("/by-key/{key}")
    public ResponseEntity<List<Parameter>> getByKey(@PathVariable String key) {
        return ResponseEntity.ok(parameterService.getParametersByKey(key));
    }

    /**
     * Get all parameters matching a key prefix for a specific headquarters.
     */
    @GetMapping("/by-prefix")
    public ResponseEntity<List<Parameter>> getByPrefix(@RequestParam String prefix,
                                                       @RequestParam(required = false) Long hqId) {
        if (hqId != null) {
            return ResponseEntity.ok(parameterService.getParametersByKeyPrefix(prefix, hqId));
        }
        return ResponseEntity.ok(parameterService.getParametersByKeyPrefix(prefix));
    }

    /**
     * Create or update a parameter.
     */
    @PostMapping
    public ResponseEntity<Parameter> save(@RequestBody Parameter parameter) {
        return ResponseEntity.ok(parameterService.save(parameter));
    }

    /**
     * Set a parameter value (create or update).
     */
    @PutMapping("/set")
    public ResponseEntity<Parameter> setValue(@RequestParam String key,
                                             @RequestParam String value,
                                             @RequestParam Long hqId,
                                             @RequestParam(required = false, defaultValue = "0") Long empId) {
        return ResponseEntity.ok(parameterService.setParameterValue(key, value, hqId, empId));
    }

    /**
     * Update value of an existing parameter by ID.
     */
    @PutMapping("/{id}/value")
    public ResponseEntity<Void> updateValue(@PathVariable Long id, @RequestBody String value) {
        parameterService.updateValue(id, value);
        return ResponseEntity.ok().build();
    }
}
