package vn.azteam.tpf.web.rest;

import com.codahale.metrics.annotation.Timed;
import org.apache.commons.io.FileUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.xmlbeans.XmlException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import vn.azteam.tpf.service.ReportsService;
import vn.azteam.tpf.service.TBCropQueryService;
import vn.azteam.tpf.service.UserService;
import vn.azteam.tpf.service.dto.*;
import vn.azteam.tpf.web.rest.errors.BadRequestAlertException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * REST controller for managing TBLimits.
 */
@RestController
@RequestMapping("/api")
public class ReportsResource {

    private final Logger log = LoggerFactory.getLogger(ReportsResource.class);

    private static final String ENTITY_NAME = "reports";
    private final String DATE_PARAM_FORMAT = "dd-MM-yyyy";

    private final ReportsService reportsService;

    private final UserService userService;

    private final TBCropResource tbCropResource;

    private ResourceLoader resourceLoader;

    private final TBCropQueryService tBCropQueryService;

    @Autowired
    private ServletContext servletContext;

    public ReportsResource(
        ReportsService reportsService,
        UserService userService,
        TBCropResource tbCropResource,
        ResourceLoader resourceLoader,
        TBCropQueryService tBCropQueryService) {
        this.reportsService = reportsService;
        this.userService = userService;
        this.tbCropResource = tbCropResource;
        this.resourceLoader = resourceLoader;
        this.tBCropQueryService = tBCropQueryService;
    }


    @GetMapping("/report/garden-supervision")
    @Timed
    public void downloadGardenSupervisionReport(
        @RequestParam("startDate") @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date startDate,
        @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date endDate,
        HttpServletResponse response) throws IOException, InvalidFormatException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentDateTime = dateFormatter.format(new Date());
        String headerValue = "attachment; filename=BaoCaoGiamSatVuon-" + currentDateTime + ".xlsx";
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);

        UserDTO currentUser = getCurrentUser();
        reportsService.exportGardenSupervisionToExcel(currentUser.getCustomerId(), startDate, endDate, response);
    }

    @GetMapping("/report/import-export-warehouse")
    @Timed
    public void downloadImportExportWarehouseReport(
        @RequestParam("startDate") @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date startDate,
        @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date endDate,
        HttpServletResponse response) throws IOException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentDateTime = dateFormatter.format(new Date());
        String headerValue = "attachment; filename=BaoCaoNhapXuatKho-" + currentDateTime + ".xlsx";
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);

        UserDTO currentUser = getCurrentUser();
        reportsService.downloadImportExportWarehouseReport(currentUser.getCustomerId(), startDate, endDate, response);
    }

    @GetMapping("/report/import-export-supplies-in-warehouse")
    @Timed
    public void downloadImportExportSuppliesInWarehouseReport(
        @Valid ReportImportExportSuppliesInWareHouseCriteria criteria,
        HttpServletResponse response) throws IOException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentDateTime = dateFormatter.format(new Date());
        String headerValue = "attachment; filename=BaoCaoNhapXuatTonVatTu-" + currentDateTime + ".xlsx";
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);

        UserDTO currentUser = getCurrentUser();
        criteria.setCustomerId(currentUser.getCustomerId());
        reportsService.downloadImportExportSuppliesInWarehouseReport(criteria, response);
    }

    @GetMapping("/report/import-material")
    @Timed
    public void downloadImportMaterialReport(
        @RequestParam("startDate") @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date startDate,
        @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date endDate,
        HttpServletResponse response) throws IOException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentDateTime = dateFormatter.format(new Date());
        String headerValue = "attachment; filename=BaoCaoTheoDoiNhapVatLieuDauVao-" + currentDateTime + ".xlsx";
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);

        UserDTO currentUser = getCurrentUser();
        reportsService.downloadImportMaterialReport(currentUser.getCustomerId(), startDate, endDate, response);
    }

    private UserDTO getCurrentUser() {
        UserDTO currentUser = userService.getCurrentUserDTO().get();
        if (currentUser.getCustomerId() == null) {
            throw new BadRequestAlertException("1002", ENTITY_NAME, "1022");
        }
        return currentUser;
    }

    @GetMapping("/report/monthly-activity/{month}/{year}")
    @Timed
    public ResponseEntity<List<ActivityInMonthDTO>> monthlyActivity(
        @PathVariable Integer month,
        @PathVariable Integer year,
        @RequestParam(value = "cropId", required = false) Long cropId) {
        log.debug("REST request to get monthly activity");
        UserDTO currentUser = getCurrentUser();
        List<ActivityInMonthDTO> lstActivityInMonthDTO =
            reportsService.getMonthlyActivity(month, year, currentUser.getCustomerId(), cropId);

        return new ResponseEntity<>(lstActivityInMonthDTO, HttpStatus.OK);
    }

    @GetMapping("/report/seed-usage")
    @Timed
    public ResponseEntity<List<SeedUsageReportDTO>> getGiongUsageReport() {
        log.debug("REST request to get seed usage");
        List<SeedUsageReportDTO> seedUsages;
        Optional<UserDTO> currentUser = userService.getCurrentUserDTO();

        if (!currentUser.isPresent()) {
            return new ResponseEntity<>(new ArrayList<>(), HttpStatus.OK);
        }

        Long customerId = currentUser.get().getCustomerId();
        seedUsages = reportsService.getSeedUsageReport(customerId);

        return new ResponseEntity<>(seedUsages, HttpStatus.OK);
    }

    /**
     *
     * @return the ResponseEntity with status 200 (OK) and the list of nursery activity in body
     */
    @GetMapping("/report-cultivate-history/{cropId}")
    @Timed
    public void ReportCultivateHistory(
        @PathVariable Long cropId,
        @RequestParam("startDate") @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date startDate,
        @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date endDate,
        HttpServletResponse response) throws IOException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentDateTime = dateFormatter.format(new Date());
        String headerValue = "attachment; filename=BieuMauNhatKyCanhTacTaiKhuCanhTac-" + currentDateTime + ".docx";
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);

        UserDTO currentUser = getCurrentUser();
        reportsService.downloadCultivateHistoryReport(currentUser.getCustomerId(), cropId, startDate, endDate, response);
    }

    /**
     *
     * @return the ResponseEntity with status 200 (OK) and the list of nursery activity in body
     */
    @GetMapping("/report-nursery-monitor/{cropId}")
    @Timed
    public void ReportNurseryMonitor(
        @PathVariable Long cropId,
        @RequestParam("startDate") @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date startDate,
        @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = DATE_PARAM_FORMAT) Date endDate,
        HttpServletResponse response) throws IOException {

        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentDateTime = dateFormatter.format(new Date());
        String headerValue = "attachment; filename=BaoCaoTheoDoiNhaUom-" + currentDateTime + ".docx";
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);

        UserDTO currentUser = getCurrentUser();
        reportsService.downloadNurseryMonitoringReport(currentUser.getCustomerId(), cropId, startDate, endDate, response);
    }
}
