package br.gov.sigefp.budget.service;

import br.gov.sigefp.budget.api.dto.BudgetLineDTO;
import br.gov.sigefp.budget.domain.BudgetLine;
import br.gov.sigefp.budget.domain.FiscalYear;
import br.gov.sigefp.budget.repository.BudgetLineRepository;
import br.gov.sigefp.budget.repository.FiscalYearRepository;
import br.gov.sigefp.org.repository.MinistryRepository;
import br.gov.sigefp.org.repository.OrgUnitRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.math.BigDecimal;
import java.util.Optional;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class BudgetLineServiceTest {

    @Mock
    private BudgetLineRepository budgetLineRepository;
    @Mock
    private FiscalYearRepository fiscalYearRepository;
    @Mock
    private MinistryRepository ministryRepository;
    @Mock
    private OrgUnitRepository orgUnitRepository;

    @InjectMocks
    private BudgetLineService budgetLineService;

    private BudgetLine budgetLine;

    @BeforeEach
    void setUp() {
        FiscalYear fiscalYear = FiscalYear.builder().year(2025).status("OPEN").build();
        fiscalYear.setId(UUID.randomUUID());

        budgetLine = BudgetLine.builder()
                .id(UUID.randomUUID())
                .code("01.01")
                .description("Teste")
                .fiscalYear(fiscalYear)
                .totalAllocated(new BigDecimal("1000"))
                .totalCommitted(new BigDecimal("200"))
                .build();
    }

    @Test
    @DisplayName("Should use pre-calculated Formula fields for DTO conversion")
    void toDTO_ShouldUseFormulaFields() {
        when(budgetLineRepository.findById(budgetLine.getId())).thenReturn(Optional.of(budgetLine));

        BudgetLineDTO dto = budgetLineService.findById(budgetLine.getId());

        assertNotNull(dto);
        assertEquals(new BigDecimal("1000"), dto.getTotalAllocated());
        assertEquals(new BigDecimal("200"), dto.getTotalCommitted());
        assertEquals(new BigDecimal("800"), dto.getAvailableBalance());
        // Verify no extra repository calls are made (implicitly verified by lack of
        // mocks for them)
    }
}
