package com.devjob.job.repository;

import com.devjob.job.domain.Company;
import com.devjob.job.domain.Job;
import com.devjob.job.domain.JobStatus;
import jakarta.persistence.criteria.Join;
import java.time.LocalDate;
import org.springframework.data.jpa.domain.Specification;

public class JobSpecification {

    private JobSpecification() {
    }

    public static Specification<Job> withKeyword(String keyword) {
        return (root, query, cb) -> {
            if (keyword == null || keyword.isBlank()) {
                return null;
            }
            Join<Job, Company> company = root.join("company");
            return cb.or(
                    cb.like(cb.lower(root.get("title")), "%" + keyword.toLowerCase() + "%"),
                    cb.like(cb.lower(company.get("name")), "%" + keyword.toLowerCase() + "%")
            );
        };
    }

    public static Specification<Job> withLocation(String location) {
        return (root, query, cb) -> {
            if (location == null || location.isBlank()) {
                return null;
            }
            return cb.equal(root.join("company").get("location"), location);
        };
    }

    public static Specification<Job> withStatus(JobStatus status) {
        return (root, query, cb) -> {
            if (status == null) {
                return null;
            }
            return cb.equal(root.get("status"), status);
        };
    }

    public static Specification<Job> withSalaryGoe(Integer minSalary) {
        return (root, query, cb) -> {
            if (minSalary == null) {
                return null;
            }
            return cb.greaterThanOrEqualTo(root.get("salary"), minSalary);
        };
    }

    public static Specification<Job> withSalaryLoe(Integer maxSalary) {
        return (root, query, cb) -> {
            if (maxSalary == null) {
                return null;
            }
            return cb.lessThanOrEqualTo(root.get("salary"), maxSalary);
        };
    }

    public static Specification<Job> withDeadlineBefore(LocalDate date) {
        return (root, query, cb) -> {
            if (date == null) {
                return null;
            }
            return cb.lessThanOrEqualTo(root.get("deadline"), date);
        };
    }
}
