package com.utopiaindustries.controller;

import com.utopiaindustries.auth.ReportingRole;
import com.utopiaindustries.model.ctp.POsDetails;
import com.utopiaindustries.model.ctp.SummaryInventoryReport;
import com.utopiaindustries.service.InventoryAccountService;
import com.utopiaindustries.service.PurchaseOrderService;
import com.utopiaindustries.service.ReportingService;
import com.utopiaindustries.service.SummaryInventoryReportService;
import com.utopiaindustries.util.StringUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@ReportingRole
@RequestMapping( "/reporting" )
public class ReportingController {
    private final ReportingService reportingService;
    private final SummaryInventoryReportService summaryInventoryReportService;
    private final InventoryAccountService inventoryAccountService;
    private final PurchaseOrderService purchaseOrderService;


    public ReportingController(SummaryInventoryReportService summaryInventoryReportService2, ReportingService reportingService, InventoryAccountService inventoryAccountService, PurchaseOrderService purchaseOrderService) {
        this.summaryInventoryReportService = summaryInventoryReportService2;
        this.reportingService = reportingService;
        this.inventoryAccountService = inventoryAccountService;
        this.purchaseOrderService = purchaseOrderService;
    }

    @GetMapping
    public String homePage( Model model ){
        return "redirect:/reporting/job-card-report";
    }

    @GetMapping( "/summary")
    public String summary(@RequestParam(value = "item-id", required = false ) String itemId, @RequestParam(value = "sku" , required = false) String sku, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, Model model ){

        LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(6) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now().plusDays(1) : LocalDate.parse(endDate);
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        Map<String, Map<String, List<SummaryInventoryReport>>> getDataByFilteration = summaryInventoryReportService.findByFilter(itemId,sku,startDate,endDate);
        ArrayList<LocalDate> arrayList = generateDateList(startDate1,endDate1);
        model.addAttribute("dateLimits", arrayList);
        model.addAttribute("tableData", getDataByFilteration);
        return "/reporting/inventory-summary";
    }

    @GetMapping( "/job-card-report")
    public String jobCardReport(@RequestParam( value = "job-card-id", required = false ) String jobCardId,
                                Model model, RedirectAttributes redirectAttributes ){
        if( jobCardId == null || jobCardId.isEmpty()) {
            redirectAttributes.addFlashAttribute("error", "Please Re-Select Job Card" );
            return "/reporting/job-card-report";
        }
        model.addAttribute("totalProduction",  reportingService.getTotalProduction(jobCardId));
        model.addAttribute("phasesTimes",  reportingService.getEachPhaseTotalTime(jobCardId));
        model.addAttribute("segregateItems",  reportingService.getSegregateItems(jobCardId));
        model.addAttribute("pendingStatus",  reportingService.countPendingItemsOnDifferentPhases(jobCardId));
        model.addAttribute("completeProduction",  reportingService.getCompleteProduction(jobCardId));
        model.addAttribute("jobCardProgress",  reportingService.getJobCardProgress(jobCardId));
        model.addAttribute("cuttingDetails",  reportingService.getCuttingDetails(jobCardId));
        model.addAttribute("stitchingDetails",  reportingService.getStitchingDetails(jobCardId));
        model.addAttribute("dailyProgress",  reportingService.getPhasesProgressDayWise(jobCardId));

        return "/reporting/job-card-report";
    }

    @GetMapping( value = "/cutting-report" )
    public String cuttingReport(@RequestParam(value = "job-card-id", required = false ) String jobCardId, @RequestParam(value = "accountId" , required = false) String accountId, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, @RequestParam(value = "count", required = false) Long count,  Model model ){

        LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(31) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        model.addAttribute("accounts", inventoryAccountService.getAllCuttingAccounts() );
        model.addAttribute("cutting",reportingService.getCuttingTableDetails(jobCardId, accountId, startDate1.toString(), endDate1.toString(), count));

        return "/reporting/cutting-report";
    }

    @GetMapping( value = "/stitching-report" )
    public String stitchingReport(@RequestParam(value = "job-card-id", required = false ) String jobCardId, @RequestParam(value = "accountId" , required = false) String accountId, @RequestParam(value = "start-date", required = false) String startDate, @RequestParam(value = "end-date", required = false) String endDate, @RequestParam(value = "count", required = false) Long count, Model model ){

        LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(31) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        model.addAttribute("accounts" , inventoryAccountService.findInventoryAccounts( 2L ) );
        model.addAttribute("stitching",reportingService.getStitchingDetails(jobCardId, accountId, startDate1.toString(), endDate1.toString(), count));

        return "/reporting/stitching-report";
    }

    @GetMapping( "/inventory-transactions" )
    public String getInventoryTransactionsByAccount( @RequestParam( value = "account-id", required = false) String accountId,
                                                     @RequestParam( value = "jobCard-id", required = false) String jobCardId,
                                                     @RequestParam( value = "sku", required = false) String sku,
                                                     @RequestParam( value = "startDate", required = false) String startDate,
                                                     @RequestParam( value = "endDate", required = false) String endDate,
                                                     @RequestParam(value = "count", required = false) Long count,
                                                     Model model ){

        LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(31) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        model.addAttribute("transactions", reportingService.stitchingItemsTransactions( jobCardId, accountId, sku, startDate1.toString(), endDate1.toString(), count ));
        return "/reporting/accounts-transaction-table";
    }

    private ArrayList<LocalDate> generateDateList(LocalDate start, LocalDate end) {
        ArrayList<LocalDate> localDates = new ArrayList<>();
        while (start.isBefore(end)) {
            localDates.add(start);
            start = start.plusDays(1);
        }
        return localDates;
    }
}
