package com.mvrent.carrental.service;

import com.mvrent.carrental.model.*;
import com.mvrent.carrental.repository.CarDocumentRepository;
import com.mvrent.carrental.repository.CarPhotoRepository;
import com.mvrent.carrental.repository.CarRepository;
import com.mvrent.carrental.repository.VendorRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
import java.util.Set;

@Service
@RequiredArgsConstructor
public class CarService {

    private final CarRepository carRepository;
    private final CarDocumentRepository carDocumentRepository;
    private final CarPhotoRepository carPhotoRepository;
    private final VendorRepository vendorRepository;

    public List<Car> findAll() {
        return carRepository.findAll();
    }

    /** Cars listed and operationally active (used by the public site). */
    public List<Car> findAvailable() {
        return carRepository.findByAvailableTrueAndStatus(CarStatus.ACTIVE);
    }

    public List<Car> findAvailableBetween(LocalDate pickup, LocalDate ret) {
        return carRepository.findAvailableBetween(pickup, ret);
    }

    public Car findById(Long id) {
        return carRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("Car not found: " + id));
    }

    public Car save(Car car) {
        return carRepository.save(car);
    }

    /**
     * Persist a car from the admin form. For an existing car the scalar fields are
     * copied onto the managed entity so its documents/photos collections are kept.
     */
    @Transactional
    public Car saveFromForm(Car form, Set<String> featureTags, Long vendorId) {
        Car target = form.getId() != null ? findById(form.getId()) : new Car();
        target.setMake(form.getMake());
        target.setModel(form.getModel());
        target.setRegistrationNumber(form.getRegistrationNumber());
        target.setYearOfRegistration(form.getYearOfRegistration());
        target.setColour(form.getColour());
        target.setType(form.getType());
        target.setSeats(form.getSeats());
        target.setTransmission(form.getTransmission());
        target.setFuelType(form.getFuelType());
        target.setHourlyRate(form.getHourlyRate());
        target.setPricePerDay(form.getPricePerDay());
        target.setMonthlyRate(form.getMonthlyRate());
        target.setOwnership(form.getOwnership());
        target.setUnitsTotal(form.getUnitsTotal());
        target.setStatus(form.getStatus());
        target.setImageUrl(form.getImageUrl());
        target.setAvailable(form.isAvailable());
        target.setFeatureTags(featureTags);
        // Vendor link only applies to vendor-attached cars.
        if (form.getOwnership() == CarOwnership.VENDOR && vendorId != null) {
            target.setVendor(vendorRepository.findById(vendorId).orElse(null));
            target.setCommissionPercentOverride(form.getCommissionPercentOverride());
        } else {
            target.setVendor(null);
            target.setCommissionPercentOverride(null);
        }
        return carRepository.save(target);
    }

    public void delete(Long id) {
        carRepository.deleteById(id);
    }

    /* ---------- Documents ---------- */

    @Transactional
    public CarDocument addDocument(Long carId, CarDocumentType type, String fileUrl,
                                   LocalDate issued, LocalDate expiry) {
        Car car = findById(carId);
        CarDocument doc = CarDocument.builder()
                .car(car).docType(type).fileUrl(fileUrl)
                .issuedDate(issued).expiryDate(expiry).build();
        return carDocumentRepository.save(doc);
    }

    @Transactional
    public void deleteDocument(Long docId) {
        carDocumentRepository.deleteById(docId);
    }

    public List<CarDocument> documentsExpiringWithin(int days) {
        return carDocumentRepository.findExpiringOrExpired(LocalDate.now().plusDays(days));
    }

    /* ---------- Photos ---------- */

    @Transactional
    public CarPhoto addPhoto(Long carId, String url, int sortOrder) {
        Car car = findById(carId);
        CarPhoto photo = CarPhoto.builder().car(car).url(url).sortOrder(sortOrder).build();
        return carPhotoRepository.save(photo);
    }

    @Transactional
    public void deletePhoto(Long photoId) {
        carPhotoRepository.deleteById(photoId);
    }
}
