package com.nebula.erp.product.service;

import com.nebula.erp.product.model.Coupon;
import com.nebula.erp.product.model.Product;
import com.nebula.erp.product.repository.CouponRepository;
import com.nebula.erp.product.requestmodel.CouponRequest;
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.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Optional;
import org.springframework.data.domain.Sort;

@Service
public class CouponService {

    @Autowired
    private CouponRepository couponRepository;

    @Autowired
    private JwtRequestUtils jwtRequestUtils;

    @Autowired
    private CreateLogger createLogger;

    private static final String path = "/coupons";

    public Page<Coupon> getAllCoupons(int page, int size, String coupon_code, String search) {
        String tenantName = jwtRequestUtils.getTenantName();

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

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

        Specification<Coupon> spec = Specification.where(null);

        if (coupon_code != null) {
            spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("code"), coupon_code));
        }

        if (!"ALL".equals(tenantName)) {
            spec = spec.and((root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("tenant"), tenantName));
        }

        return couponRepository.findAll(spec, pageable);
    }

    public Coupon createCoupon(CouponRequest couponRequest) throws IOException {
        String tenantName = jwtRequestUtils.getTenantName();
        String userId = jwtRequestUtils.getUserId();

        int couponExist = couponRepository.findByCodeAndTenant(couponRequest.getCode(), tenantName);
        if (couponExist > 0) {
            createLogger.createLogger("error", path, "PUT", "Coupon code already exist", "");
            throw new IllegalArgumentException("Coupon code already exist");
        }

        // Create a new coupon object
        Coupon coupon = new Coupon();
        coupon.setName(couponRequest.getName());
        coupon.setCode(couponRequest.getCode());
        coupon.setStart_date(couponRequest.getStart_date());
        coupon.setEnd_date(couponRequest.getEnd_date());
        coupon.setPercentage(couponRequest.getPercentage());
        coupon.setCreated_by(userId);
        coupon.setTenant(tenantName);

        return couponRepository.save(coupon);
    }

    public Optional<Coupon> getCoupon(Long id) {
        String tenantName = jwtRequestUtils.getTenantName();
        return couponRepository.findByIdAndTenant(id, tenantName);
    }

    public Coupon updateCoupon(Long id, CouponRequest couponRequest) throws IOException {
        String tenantName = jwtRequestUtils.getTenantName();

        // Find the existing coupon
        Coupon coupon = couponRepository.findByIdAndTenant(id, tenantName)
                .orElseThrow(() -> new RuntimeException("Coupon not found"));

        int couponExist = couponRepository.findByCodeANDIdAndTenant(id, couponRequest.getCode(), tenantName);
        if (couponExist > 0) {
            createLogger.createLogger("error", path, "PUT", "Coupon code already exist", "");
            throw new IllegalArgumentException("Coupon code already exist");
        }

        // Update the coupon details
        coupon.setName(couponRequest.getName());
        coupon.setCode(couponRequest.getCode());
        coupon.setStart_date(couponRequest.getStart_date());
        coupon.setEnd_date(couponRequest.getEnd_date());
        coupon.setPercentage(couponRequest.getPercentage());

        // Save and return the updated coupon
        return couponRepository.save(coupon);
    }

    public void deleteCoupon(Long id) {
        String tenantName = jwtRequestUtils.getTenantName();
        couponRepository.findByIdAndTenant(id, tenantName).orElseThrow(() -> new RuntimeException("Coupon not found"));
        couponRepository.deleteById(id);
    }

}
