package de.votian.services.service;

import de.votian.services.entity.Company;
import de.votian.services.entity.CostCenter;
import de.votian.services.entity.Courier;
import de.votian.services.entity.Customer;
import de.votian.services.entity.Job;
import de.votian.services.entity.Tour;
import de.votian.services.entity.TourArticle;
import de.votian.services.repository.CompanyRepository;
import de.votian.services.repository.CostCenterRepository;
import de.votian.services.repository.CourierRepository;
import de.votian.services.repository.CustomerRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Objects;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class JobBatchService {

    private final JobService jobService;
    private final CustomerRepository customerRepository;
    private final CostCenterRepository costCenterRepository;
    private final CompanyRepository companyRepository;
    private final CourierRepository courierRepository;

    public JobBatchService(JobService jobService,
                           CustomerRepository customerRepository,
                           CostCenterRepository costCenterRepository,
                           CompanyRepository companyRepository,
                           CourierRepository courierRepository) {
        this.jobService = jobService;
        this.customerRepository = customerRepository;
        this.costCenterRepository = costCenterRepository;
        this.companyRepository = companyRepository;
        this.courierRepository = courierRepository;
    }

    public List<Job> createBatchJobs(Long hqId,
                                     Long customerId,
                                     Long costCenterId,
                                     List<BatchJobRow> rows) {
        if (rows == null || rows.isEmpty()) {
            return List.of();
        }

        Customer customer = customerRepository.findById(Objects.requireNonNull(customerId))
                .orElseThrow(() -> new IllegalArgumentException("Kunde nicht gefunden: " + customerId));
        if (!hqId.equals(customer.getHeadquartersId())) {
            throw new IllegalArgumentException("Kunde gehoert nicht zur aktiven Niederlassung.");
        }

        CostCenter costCenter = costCenterRepository.findById(Objects.requireNonNull(costCenterId))
                .orElseThrow(() -> new IllegalArgumentException("Kostenstelle nicht gefunden: " + costCenterId));
        if (!customerId.equals(costCenter.getCustomerId())) {
            throw new IllegalArgumentException("Kostenstelle gehoert nicht zum Kunden.");
        }

        Company company = companyRepository.findById(Objects.requireNonNull(customer.getCompanyId()))
                .orElseThrow(() -> new IllegalArgumentException("Firma des Kunden nicht gefunden."));
        String customerName = firstNonBlank(company.getComp(), customer.getEid(), "Listenbuchung");

        List<Job> createdJobs = new ArrayList<>();
        for (BatchJobRow row : rows) {
            if (row == null || row.orderTime() == null || !hasText(row.description()) || row.totalPrice() == null) {
                continue;
            }

            Courier courier = null;
            if (row.courierId() != null) {
                courier = courierRepository.findById(Objects.requireNonNull(row.courierId()))
                        .orElseThrow(() -> new IllegalArgumentException("Kurier nicht gefunden: " + row.courierId()));
                if (!hqId.equals(courier.getHeadquartersId())) {
                    throw new IllegalArgumentException("Kurier gehoert nicht zur aktiven Niederlassung.");
                }
            }

            Job job = new Job();
            job.setHeadquartersId(hqId);
            job.setHeadquartersDispoId(hqId);
            job.setCostCenterPayerId(costCenterId);
            job.setCostCenterRelatedId(costCenterId);
            job.setOrderTime(row.orderTime());
            job.setBookTime(row.orderTime());
            job.setFinishTime(row.orderTime());
            job.setStatus(9);
            job.setTourName(row.description());
            job.setInvoiceText(row.description());
            job.setTotalPrice(row.totalPrice());
            job.setCourierPrice(row.courierPrice() != null ? row.courierPrice() : BigDecimal.ZERO);
            if (courier != null) {
                job.setCourierId(courier.getId());
                job.setCourierSid(courier.getSid());
                job.setVehicleTypeId(courier.getVehicleTypeId());
            }

            Tour pickup = new Tour();
            pickup.setSort(1);
            pickup.setComp(customerName);
            pickup.setCommissionNo(row.commissionNo());
            pickup.setStatus(1);
            pickup.setCostCenterId(costCenterId);
            pickup.setAddressId(company.getAddressId());

            Tour delivery = new Tour();
            delivery.setSort(2);
            delivery.setComp(customerName);
            delivery.setCommissionNo(row.commissionNo());
            delivery.setStatus(1);
            delivery.setCostCenterId(costCenterId);
            delivery.setAddressId(company.getAddressId());

            createdJobs.add(jobService.createJob(job, List.of(pickup, delivery), List.<TourArticle>of()));
        }

        return createdJobs;
    }

    private boolean hasText(String value) {
        return value != null && !value.isBlank();
    }

    private String firstNonBlank(String... values) {
        for (String value : values) {
            if (hasText(value)) {
                return value;
            }
        }
        return "";
    }

    public record BatchJobRow(LocalDateTime orderTime,
                              String description,
                              String commissionNo,
                              BigDecimal totalPrice,
                              BigDecimal courierPrice,
                              Long courierId) {
    }
}
