package com.nebula.erp.product.service;

import com.nebula.erp.product.model.Product;
import com.nebula.erp.product.model.Tax;
import com.nebula.erp.product.repository.ProductRepository;
import com.nebula.erp.product.repository.TaxRepository;
import com.nebula.erp.product.requestmodel.TaxRequest;
import com.nebula.erp.product.utility.CreateLogger;
import com.nebula.erp.product.utility.JwtRequestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import org.springframework.data.domain.Sort;

@Service
public class TaxService {
    @Autowired
    private TaxRepository taxRepository;

    @Autowired
    private JwtRequestUtils jwtRequestUtils;

    @Autowired
    private CreateLogger createLogger;

    @Autowired
    private ProductRepository productRepository;

    private static final String path = "/tax";

    public Page<Tax> getAllTax(int page, int size, String search) {
        String tenantName = jwtRequestUtils.getTenantName();

        Pageable pageable = PageRequest.of(
                page - 1,
                size,
                Sort.by(Sort.Direction.DESC, "created_at"));

        // SEARCH (no length restriction)
        if (search != null && !search.trim().isEmpty()) {
            return taxRepository.searchTaxes(
                    tenantName,
                    "%" + search.toLowerCase() + "%",
                    pageable);
        }

        return taxRepository.findAllByTenant(pageable, tenantName);
    }

    public Tax createTax(TaxRequest taxRequest) {
        // Validate required fields
        if (taxRequest.getType() == null || taxRequest.getRate() == null) {
            throw new IllegalArgumentException("Tax type and rate is required");
        }
        String tenantName = jwtRequestUtils.getTenantName();
        String userId = jwtRequestUtils.getUserId();

        // Create a new Tax object
        Tax tax = new Tax();
        tax.setType(taxRequest.getType());
        tax.setRate(taxRequest.getRate());
        tax.setCreated_by(userId);
        tax.setTenant(tenantName);
        // NEW: Handle CGST/SGST split
        boolean isSplit = Boolean.TRUE.equals(taxRequest.getIsSplit());
        tax.setIsSplit(isSplit);
        if (isSplit) {
            BigDecimal total = taxRequest.getRate();
            BigDecimal half = total.divide(java.math.BigDecimal.valueOf(2));
            tax.setCgstRate(half);
            tax.setSgstRate(half);
        } else {
            tax.setCgstRate(null);
            tax.setSgstRate(null);
        }

        return taxRepository.save(tax);
    }

    public Optional<Tax> getTax(Long id) {
        String tenantName = jwtRequestUtils.getTenantName();
        return taxRepository.findByIdAndTenant(id, tenantName);
    }

    public Tax updateTax(Long id, TaxRequest taxRequest) {
        String tenantName = jwtRequestUtils.getTenantName();
        // Find the existing Tax
        Tax tax = taxRepository.findByIdAndTenant(id, tenantName)
                .orElseThrow(() -> new RuntimeException("Tax not found"));

        // Update the Tax details
        tax.setType(taxRequest.getType());
        tax.setRate(taxRequest.getRate());
        // NEW: Handle CGST/SGST split
        boolean isSplit = Boolean.TRUE.equals(taxRequest.getIsSplit());
        tax.setIsSplit(isSplit);
        if (isSplit) {
            BigDecimal half = taxRequest.getRate().divide(java.math.BigDecimal.valueOf(2));
            tax.setCgstRate(half);
            tax.setSgstRate(half);
        } else {
            tax.setCgstRate(null);
            tax.setSgstRate(null);
        }

        return taxRepository.save(tax);
    }

    public void deleteTax(Long id) {
        String tenantName = jwtRequestUtils.getTenantName();

        taxRepository.findByIdAndTenant(id, tenantName).orElseThrow(() -> new RuntimeException("Tax not found"));

        // Check if there are any products associated with the brand
        List<Product> associatedProducts = productRepository.findProductsByTaxId(id);
        if (!associatedProducts.isEmpty()) {
            createLogger.createLogger("error", path, "DELETE",
                    "Cannot delete tax because it is associated with one or more products", "");
            throw new RuntimeException("Cannot delete tax because it is associated with one or more products");
        }

        taxRepository.deleteById(id);
    }

}