package org.raddatz.familienarchiv.geschichte;

import lombok.RequiredArgsConstructor;
import org.raddatz.familienarchiv.geschichte.journeyitem.JourneyItemCreateDTO;
import org.raddatz.familienarchiv.geschichte.journeyitem.JourneyItemService;
import org.raddatz.familienarchiv.geschichte.journeyitem.JourneyItemUpdateDTO;
import org.raddatz.familienarchiv.geschichte.journeyitem.JourneyItemView;
import org.raddatz.familienarchiv.geschichte.journeyitem.JourneyReorderDTO;
import org.raddatz.familienarchiv.security.Permission;
import org.raddatz.familienarchiv.security.RequirePermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/geschichten")
@RequiredArgsConstructor
public class GeschichteController {

    private final GeschichteService geschichteService;
    private final JourneyItemService journeyItemService;

    @GetMapping
    public List<GeschichteSummary> list(
            @Parameter(description = "Filter by status. Callers without BLOG_WRITE always receive PUBLISHED results regardless of the value passed. Callers with BLOG_WRITE requesting DRAFT receive only their own unpublished stories.")
            @RequestParam(required = false) GeschichteStatus status,
            @Parameter(description = "AND-filter: story must include all supplied person IDs.")
            @RequestParam(name = "personId", required = false) List<UUID> personIds,
            @Parameter(description = "Filter to stories containing this document.")
            @RequestParam(required = false) UUID documentId,
            @Parameter(description = "Maximum results to return. Values ≤ 0 default to 50. Clamped at 200.")
            @RequestParam(required = false, defaultValue = "50") int limit) {
        return geschichteService.list(
                status,
                personIds == null ? List.of() : personIds,
                documentId,
                limit);
    }

    @GetMapping("/{id}")
    public GeschichteView getById(@PathVariable UUID id) {
        return geschichteService.getView(id);
    }

    @PostMapping
    @RequirePermission(Permission.BLOG_WRITE)
    public ResponseEntity<GeschichteView> create(@RequestBody GeschichteUpdateDTO dto) {
        GeschichteView created = geschichteService.create(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }

    @PatchMapping("/{id}")
    @RequirePermission(Permission.BLOG_WRITE)
    public GeschichteView update(@PathVariable UUID id, @RequestBody GeschichteUpdateDTO dto) {
        return geschichteService.update(id, dto);
    }

    @DeleteMapping("/{id}")
    @RequirePermission(Permission.BLOG_WRITE)
    public ResponseEntity<Void> delete(@PathVariable UUID id) {
        geschichteService.delete(id);
        return ResponseEntity.noContent().build();
    }

    // ─── JourneyItem CRUD ────────────────────────────────────────────────────

    @PostMapping("/{id}/items")
    @RequirePermission(Permission.BLOG_WRITE)
    public ResponseEntity<JourneyItemView> appendItem(
            @PathVariable UUID id,
            @RequestBody JourneyItemCreateDTO dto) {
        JourneyItemView view = journeyItemService.append(id, dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(view);
    }

    @PatchMapping("/{id}/items/{itemId}")
    @RequirePermission(Permission.BLOG_WRITE)
    public JourneyItemView updateItemNote(
            @PathVariable UUID id,
            @PathVariable UUID itemId,
            @RequestBody JourneyItemUpdateDTO dto) {
        return journeyItemService.updateNote(id, itemId, dto);
    }

    @DeleteMapping("/{id}/items/{itemId}")
    @RequirePermission(Permission.BLOG_WRITE)
    public ResponseEntity<Void> deleteItem(
            @PathVariable UUID id,
            @PathVariable UUID itemId) {
        journeyItemService.delete(id, itemId);
        return ResponseEntity.noContent().build();
    }

    @PutMapping("/{id}/items/reorder")
    @RequirePermission(Permission.BLOG_WRITE)
    @Operation(
        summary = "Reorder journey items",
        description = "itemIds must contain ALL item IDs for the given journey in the desired new order. Sending a partial list returns 400 Bad Request."
    )
    public List<JourneyItemView> reorderItems(
            @PathVariable UUID id,
            @RequestBody JourneyReorderDTO dto) {
        return journeyItemService.reorder(id, dto);
    }
}
