package com.fsd.hellovelo.service;

import com.fsd.hellovelo.entity.*;
import com.fsd.hellovelo.exceptions.ResourceNotFoundException;
import com.fsd.hellovelo.payload.request.BikeTransferRequest;
import com.fsd.hellovelo.payload.request.MaintenanceTransferRequest;
import com.fsd.hellovelo.payload.request.UpdateBikeRequest;
import com.fsd.hellovelo.repository.BikeRepository;
import com.fsd.hellovelo.repository.MaintenanceRepository;
import com.fsd.hellovelo.repository.ReportRepository;
import com.fsd.hellovelo.repository.StationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class MaintenanceService {

    private final MaintenanceRepository maintenanceRepository;
    private final BikeRepository bikeRepository;
    private final StationRepository stationRepository;
    private final ReportRepository reportRepository;
    private final  ReportService reportService;


    @Autowired
    public MaintenanceService(MaintenanceRepository maintenanceRepository, BikeRepository bikeRepository,
                              StationRepository stationRepository, ReportRepository reportRepository, ReportService reportService
    ){
        this.maintenanceRepository = maintenanceRepository;
        this.bikeRepository = bikeRepository;
        this.stationRepository = stationRepository;
        this.reportService = reportService;
        this.reportRepository = reportRepository;
    }


    public List<Bike> findAllBikesDueForMaintenance(){
        List<Bike> bikeList = bikeRepository.findAllByStatusIsNot(EStatus.DISABLED);
        List<Bike> dueList = new ArrayList<>();
        for (Bike bike:
                bikeList) {
            LocalDate date1 = LocalDate.now();
            LocalDate date2 = bike.getLastMaintenance();

            long diffInDays = Math.abs(ChronoUnit.DAYS.between(date1, date2));
            System.out.println(diffInDays);
            if ((diffInDays >= 7 && !bike.isCurrentlyInUse()) || (bike.getStatus().equals(EStatus.InMAINTENANCE)) ) {
                bike.setStatus(EStatus.InMAINTENANCE);
                bike.setStation(stationRepository.getById(1L));
                bikeRepository.save(bike);
                dueList.add(bike);
            }
        }
        return dueList;
    }

//    public List<Maintenance> getAllMaintenance(){
//        return maintenanceRepository.findAll();
//    }

    public void makeBikeStatusActiveAfterMaintenance(Long bikeId) {
        boolean exists = bikeRepository.existsById(bikeId);
        if (!exists) {
            throw new ResourceNotFoundException("Bike does not exist with id: " + bikeId);
        }
        Bike bike = bikeRepository.findById(bikeId).get();
        bike.setLastMaintenance(LocalDate.now());
        bike.setStatus(EStatus.ACTIVE);
        bikeRepository.save(bike);
        Maintenance newMaintenance = new Maintenance();
        newMaintenance.setMaintenanceDate(LocalDate.now());
        newMaintenance.setMaintainedBike(bike);
        maintenanceRepository.save(newMaintenance);
    }


    public void sendReportedBikeToMaintenance(Long reportId) {
        boolean exists = reportRepository.existsById(reportId);
        if (!exists) {
            throw new ResourceNotFoundException("Report does not exist with id: " + reportId);
        }
        Report report = reportRepository.findById(reportId).get();
        if (report.getBike() == null){
            throw new ResourceNotFoundException("Bike does not exist in report with id: " + reportId);
        }
        Bike bike = report.getBike();
        LocalDate reportDate = report.getReportTime().toLocalDate();
        if (reportDate.isBefore(bike.getLastMaintenance())){
            throw new IllegalArgumentException("This bike has been serviced after this report ");
        }
        if(!bike.isCurrentlyInUse() && reportDate.isAfter(bike.getLastMaintenance()) && bike.getStatus() != EStatus.InMAINTENANCE ){
        bike.setStatus(EStatus.InMAINTENANCE);
        bikeRepository.save(bike);
        }
    }


//    public Bike transferMaintainedBikeToWarehouse(@Valid BikeTransferRequest bikeTransferRequest) {
//        List<Bike> bikes = bikeRepository.findByIdIn(bikeTransferRequest.getCheckboxOptions());
//        if(bikes.isEmpty()) {
//            throw new ResourceNotFoundException("Selected bikes do not exist");
//        }
//        for (Bike bike: bikes) {
//            bike.setStation();
//        }
//        bikeRepository.saveAll(bikes);
//        return bikeTransferRequest.getTransferStation();
//    }


//    public List<Maintenance> transferBikesToMaintenance(@Valid MaintenanceTransferRequest maintenanceTransferRequest) {
//
//        List<Bike> bikes = bikeRepository.findByIdIn(maintenanceTransferRequest.getCheckboxOptions());
//        if(bikes.isEmpty()) {
//            throw new ResourceNotFoundException("Selected bikes do not exist");
//        }
//
//        List<Maintenance> maintainedBikeList= new ArrayList<Maintenance>();
//
//
//        for (Bike bike: bikes) {
//            bike.setStation(stationRepository.getById(1L));
//            Maintenance newMaintenance = new Maintenance();
//            newMaintenance.setMaintenanceDate(LocalDate.now());
//            newMaintenance.setMaintainedBike(bike);
//            maintenanceRepository.save(newMaintenance);
//            maintainedBikeList.add(newMaintenance);
//        }
//        bikeRepository.saveAll(bikes);
//        return maintainedBikeList;
//
//    }


    public List<Maintenance> findAllMaintenanceHistory(){
        return maintenanceRepository.findAll();
    }




}
