package br.gov.sigefp.treasury.api;

import br.gov.sigefp.treasury.api.dto.CreatePaymentOrderDTO;
import br.gov.sigefp.treasury.api.dto.GenerateOrdersFromPayrollRunDTO;
import br.gov.sigefp.treasury.api.dto.PaymentOrderDTO;
import br.gov.sigefp.treasury.api.dto.UpdateStatusDTO;
import br.gov.sigefp.treasury.service.PaymentOrderService;
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 ordens de pagamento.
 */
@RestController
@RequestMapping("/api/treasury/payment-orders")
@RequiredArgsConstructor
public class PaymentOrderController {

    private final PaymentOrderService paymentOrderService;

    @GetMapping
    public ResponseEntity<?> findAll(
            @RequestParam(name = "batchId", required = false) UUID batchId,
            @RequestParam(name = "status", required = false) String status,
            @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) {

        // Se há filtros, retornar lista (sem paginação)
        if (batchId != null || status != null) {
            List<PaymentOrderDTO> result;
            if (batchId != null && status != null) {
                result = paymentOrderService.findByPaymentBatchIdAndStatus(batchId, status);
            } else if (batchId != null) {
                result = paymentOrderService.findByPaymentBatchId(batchId);
            } else {
                result = paymentOrderService.findByStatus(status);
            }
            return ResponseEntity.ok(result);
        }

        // Sem filtros, retornar paginado
        Sort sort = sortBy != null
                ? Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
                : Sort.by(Sort.Direction.DESC, "createdAt");

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

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

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

    @PostMapping("/{id}/status")
    public ResponseEntity<PaymentOrderDTO> updateStatus(
            @PathVariable UUID id,
            @Valid @RequestBody UpdateStatusDTO dto) {
        try {
            PaymentOrderDTO updated = paymentOrderService.updateStatus(id, dto.getStatus());
            return ResponseEntity.ok(updated);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }

    /**
     * Gerar ordens de pagamento a partir de uma execução de folha.
     * POST /api/treasury/payment-orders/generate-from-payroll
     */
    @PostMapping("/generate-from-payroll")
    public ResponseEntity<List<PaymentOrderDTO>> generateFromPayrollRun(
            @Valid @RequestBody GenerateOrdersFromPayrollRunDTO dto) {
        try {
            List<PaymentOrderDTO> orders = paymentOrderService.generateOrdersInternal(
                    dto.getPayrollRunId(),
                    dto.getPaymentBatchId());
            return ResponseEntity.status(HttpStatus.CREATED).body(orders);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        } catch (RuntimeException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}
