package de.votian.services.controller;

import de.votian.services.dto.UserSessionDto;
import de.votian.services.entity.Courier;
import de.votian.services.entity.CourierVehicle;
import de.votian.services.entity.Customer;
import de.votian.services.entity.Job;
import de.votian.services.repository.CourierVehicleRepository;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.CourierService;
import de.votian.services.service.CustomerService;
import de.votian.services.service.JobService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/search")
public class SearchController {

    private final CustomerService customerService;
    private final CourierService courierService;
    private final JobService jobService;
    private final CourierVehicleRepository courierVehicleRepository;
    private final AccessControlService accessControlService;

    public SearchController(CustomerService customerService,
                            CourierService courierService,
                            JobService jobService,
                            CourierVehicleRepository courierVehicleRepository,
                            AccessControlService accessControlService) {
        this.customerService = customerService;
        this.courierService = courierService;
        this.jobService = jobService;
        this.courierVehicleRepository = courierVehicleRepository;
        this.accessControlService = accessControlService;
    }

    @GetMapping
    public ResponseEntity<Map<String, Object>> globalSearch(@RequestParam String term,
                                                            @RequestParam Long hqId,
                                                            @RequestParam(required = false) String type,
                                                            Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canAccessHeadquarters(user, hqId)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }

        Map<String, Object> results = new HashMap<>();

        if ((type == null || "customer".equals(type)) && accessControlService.canViewCustomers(user)) {
            List<Customer> customers = customerService.search(hqId, term);
            results.put("customers", customers);
        }

        if ((type == null || "courier".equals(type)) && accessControlService.canViewCouriers(user)) {
            List<Courier> couriers = courierService.search(hqId, term);
            results.put("couriers", couriers);
        }

        if ((type == null || "job".equals(type)) && accessControlService.canViewJobs(user)) {
            try {
                Long jobId = Long.parseLong(term);
                jobService.findById(jobId)
                        .filter(job -> accessControlService.canAccessJob(user, job))
                        .ifPresent(job -> results.put("jobs", List.of(job)));
            } catch (NumberFormatException e) {
                List<Job> jobs = jobService.findByCommissionNoAndCustomer(term, null).stream()
                        .filter(job -> accessControlService.canAccessJob(user, job))
                        .toList();
                results.put("jobs", jobs);
            }
        }

        if ((type == null || "vehicle".equals(type)) && accessControlService.canViewCouriers(user)) {
            List<CourierVehicle> vehicles = courierVehicleRepository.searchBySidAndHq(hqId, term);
            results.put("vehicles", vehicles);
        }

        return ResponseEntity.ok(results);
    }
}
