package br.gov.sigefp.org.api;

import br.gov.sigefp.org.api.dto.OrgUnitDTO;
import br.gov.sigefp.org.service.OrgUnitService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

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

/**
 * Controller REST para gestão de unidades organizacionais.
 */
@RestController
@RequestMapping("/api/org/org-units")
@RequiredArgsConstructor
public class OrgUnitController {

    private final OrgUnitService orgUnitService;

    @GetMapping
    public ResponseEntity<?> findAll(
            @RequestParam(value = "ministryId", required = false) UUID ministryId,
            @RequestParam(value = "parentUnitId", required = false) UUID parentUnitId,
            @RequestParam(value = "page", defaultValue = "0") int page,
            @RequestParam(value = "size", defaultValue = "20") int size,
            @RequestParam(value = "sortBy", required = false) String sortBy,
            @RequestParam(value = "sortDirection", required = false, defaultValue = "ASC") String sortDirection) {
        
        // Se há filtros, retornar lista (sem paginação)
        if (ministryId != null || parentUnitId != null) {
            List<OrgUnitDTO> result;
            if (ministryId != null) {
                result = orgUnitService.findByMinistryId(ministryId);
                if (parentUnitId != null) {
                    result = result.stream()
                            .filter(ou -> parentUnitId.equals(ou.getParentUnitId()))
                            .toList();
                }
            } else {
                // Apenas parentUnitId - buscar todas e filtrar
                result = orgUnitService.findAll(PageRequest.of(0, Integer.MAX_VALUE)).getContent().stream()
                        .filter(ou -> parentUnitId.equals(ou.getParentUnitId()))
                        .toList();
            }
            return ResponseEntity.ok(result);
        }
        
        // Sem filtros, retornar paginado
        Sort sort = sortBy != null 
            ? Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
            : Sort.by(Sort.Direction.ASC, "code");
        
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<OrgUnitDTO> result = orgUnitService.findAll(pageable);
        return ResponseEntity.ok(result);
    }

    @GetMapping("/tree/{ministryId}")
    public ResponseEntity<List<OrgUnitDTO>> findTreeByMinistry(@PathVariable("ministryId") UUID ministryId) {
        try {
            List<OrgUnitDTO> tree = orgUnitService.findTreeByMinistryId(ministryId);
            return ResponseEntity.ok(tree);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @GetMapping("/{id}")
    public ResponseEntity<OrgUnitDTO> findById(@PathVariable("id") UUID id) {
        try {
            OrgUnitDTO dto = orgUnitService.findById(id);
            return ResponseEntity.ok(dto);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping
    public ResponseEntity<OrgUnitDTO> create(@Valid @RequestBody OrgUnitDTO dto) {
        try {
            OrgUnitDTO created = orgUnitService.create(dto);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }

    @PutMapping("/{id}")
    public ResponseEntity<OrgUnitDTO> update(
            @PathVariable("id") UUID id,
            @Valid @RequestBody OrgUnitDTO dto) {
        try {
            OrgUnitDTO updated = orgUnitService.update(id, dto);
            return ResponseEntity.ok(updated);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }
}

