package br.gov.sigefp.budget.api;

import br.gov.sigefp.budget.api.dto.FiscalYearDTO;
import br.gov.sigefp.budget.service.FiscalYearService;
import br.gov.sigefp.common.exception.BusinessException;
import br.gov.sigefp.common.exception.ResourceNotFoundException;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.UUID;

/**
 * Controller REST para gestão de anos fiscais.
 */
@RestController
@RequestMapping("/api/budget/fiscal-years")
@RequiredArgsConstructor
@Slf4j
public class FiscalYearController {

    private final FiscalYearService fiscalYearService;

    @GetMapping
    public ResponseEntity<Page<FiscalYearDTO>> findAll(
            @RequestParam(name = "page", defaultValue = "0") int page,
            @RequestParam(name = "size", defaultValue = "20") int size,
            @RequestParam(name = "sortBy", required = false) String sortBy,
            @RequestParam(name = "sortDirection", required = false, defaultValue = "DESC") String sortDirection) {

        Sort sort = sortBy != null
                ? Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
                : Sort.by(Sort.Direction.DESC, "year");

        Pageable pageable = PageRequest.of(page, size, sort);
        Page<FiscalYearDTO> result = fiscalYearService.findAll(pageable);
        return ResponseEntity.ok(result);
    }

    @GetMapping("/current")
    public ResponseEntity<FiscalYearDTO> getCurrent() {
        try {
            FiscalYearDTO dto = fiscalYearService.getCurrentFiscalYear();
            return ResponseEntity.ok(dto);
        } catch (ResourceNotFoundException | IllegalArgumentException e) {
            log.warn("Ano fiscal corrente não encontrado");
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            log.error("Erro inesperado ao buscar ano fiscal corrente", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @GetMapping("/{id}")
    public ResponseEntity<FiscalYearDTO> findById(@PathVariable(name = "id") UUID id) {
        try {
            FiscalYearDTO dto = fiscalYearService.findById(id);
            return ResponseEntity.ok(dto);
        } catch (ResourceNotFoundException | IllegalArgumentException e) {
            log.warn("Ano fiscal não encontrado: {}", id);
            return ResponseEntity.notFound().build();
        } catch (Exception e) {
            log.error("Erro inesperado ao buscar ano fiscal", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @PostMapping
    public ResponseEntity<FiscalYearDTO> create(@Valid @RequestBody FiscalYearDTO dto) {
        try {
            FiscalYearDTO created = fiscalYearService.create(dto);
            return ResponseEntity.status(HttpStatus.CREATED).body(created);
        } catch (BusinessException | IllegalArgumentException e) {
            log.warn("Erro de negócio ao criar ano fiscal: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Erro inesperado ao criar ano fiscal", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @PostMapping("/{id}/open")
    public ResponseEntity<FiscalYearDTO> open(@PathVariable(name = "id") UUID id) {
        try {
            FiscalYearDTO updated = fiscalYearService.open(id);
            return ResponseEntity.ok(updated);
        } catch (ResourceNotFoundException | IllegalArgumentException e) {
            log.warn("Ano fiscal não encontrado ao abrir: {}", id);
            return ResponseEntity.notFound().build();
        } catch (BusinessException e) {
            log.warn("Erro de negócio ao abrir ano fiscal: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Erro inesperado ao abrir ano fiscal", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @PostMapping("/{id}/close")
    public ResponseEntity<FiscalYearDTO> close(@PathVariable(name = "id") UUID id) {
        try {
            FiscalYearDTO updated = fiscalYearService.close(id);
            return ResponseEntity.ok(updated);
        } catch (ResourceNotFoundException | IllegalArgumentException e) {
            log.warn("Ano fiscal não encontrado ao fechar: {}", id);
            return ResponseEntity.notFound().build();
        } catch (BusinessException e) {
            log.warn("Erro de negócio ao fechar ano fiscal: {}", e.getMessage());
            return ResponseEntity.badRequest().build();
        } catch (Exception e) {
            log.error("Erro inesperado ao fechar ano fiscal", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}
