package com.fsd.hellovelo.service;


import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.fsd.hellovelo.entity.*;
import com.fsd.hellovelo.exceptions.ResourceNotFoundException;
import com.fsd.hellovelo.payload.request.UserReportRequest;
import com.fsd.hellovelo.repository.BikeRepository;
import com.fsd.hellovelo.repository.ReportRepository;
import com.fsd.hellovelo.repository.StationRepository;
import com.fsd.hellovelo.repository.UserRepository;
import com.fsd.hellovelo.security.services.UserDetailsImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service
public class ReportService {

    @Autowired
    private ReportRepository reportRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private BikeRepository bikeRepository;
    @Autowired
    private StationRepository stationRepository;

    @Autowired
    private AmazonS3Client awsS3Client;


    public void sendReport(UserReportRequest userReportRequest, MultipartFile file) throws IOException {
        UserDetailsImpl userDetails = (UserDetailsImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if(!userDetails.isProvisionAccess()){
            throw new IllegalArgumentException("Error: User is not valid.");
        }
        User user = userRepository.findById(userDetails.getId()).orElseThrow(()-> new ResourceNotFoundException("Error: User could not be found."));
        Report report = new Report();
        if(!userReportRequest.getSerialNumber().isEmpty()) {
            Bike bike = bikeRepository.findBySerialNumberAndStatusIs(userReportRequest.getSerialNumber(), EStatus.ACTIVE).orElseThrow(()-> new ResourceNotFoundException("Error: Bike could not be found."));
            report.setBike(bike);
        }
        if(userReportRequest.getStationId() != null) {
            Station station = stationRepository.findByStatusIsAndIdIs(EStatus.ACTIVE, userReportRequest.getStationId()).orElseThrow(()-> new ResourceNotFoundException("Error: Station could not be found."));
            report.setStation(station);
        }
        if(file != null) {
            String extension = StringUtils.getFilenameExtension(file.getOriginalFilename());

            String[] values = {"png","jpeg","jpg"};
            if(Arrays.stream(values).noneMatch(extension::equals)) {
                throw new IllegalArgumentException("File extension should be png, jpeg, or jpg ");
            }
            String key = UUID.randomUUID() + "." + extension;
            ObjectMetadata metaData = new ObjectMetadata();
            metaData.setContentLength(file.getSize());
            metaData.setContentType(file.getContentType());
            awsS3Client.putObject("pyblog", key, file.getInputStream(), metaData);
            report.setImageURL(awsS3Client.getResourceUrl("pyblog", key));
        }
        report.setBody(userReportRequest.getBody());
        report.setUser(user);
        reportRepository.save(report);
    }

    public List<Report> findAllReports() {
        return reportRepository.findAll();
    }

    public void deleteReport(Long reportId) {
        boolean exists = reportRepository.existsById(reportId);
        if (!exists) {
            throw new ResourceNotFoundException("Report does not exist with id: " + reportId);
        }
        reportRepository.deleteById(reportId);
    }

    public Report getReport(Long reportId) {
        boolean exists = reportRepository.existsById(reportId);
        if (!exists) {
            throw new ResourceNotFoundException("Report does not exist with id: " + reportId);
        }
        return reportRepository.findById(reportId).get();
    }


}
