package com.utopiaindustries.controller;

import com.utopiaindustries.auth.CuttingRole;
import com.utopiaindustries.dao.ctp.BundleWrapper;
import com.utopiaindustries.model.ctp.JobCardWrapper;
import com.utopiaindustries.model.ctp.StitchingOfflineItem;
import com.utopiaindustries.service.*;
import com.utopiaindustries.util.StringUtils;
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.Arrays;
import java.util.List;

@Controller
@CuttingRole
@RequestMapping( "/cutting" )
public class CuttingController {

    private final InventoryAccountService inventoryAccountService;
    private final JobCardService jobCardService;
    private final InventoryService inventoryService;
    private final LocationService locationService;
    private final BundleService bundleService;
    private final BarcodeService barcodeService;

    public CuttingController(InventoryAccountService inventoryAccountService, JobCardService jobCardService, InventoryService inventoryService, LocationService locationService, BundleService bundleService, BarcodeService barcodeService) {
        this.inventoryAccountService = inventoryAccountService;
        this.jobCardService = jobCardService;
        this.inventoryService = inventoryService;
        this.locationService = locationService;
        this.bundleService = bundleService;
        this.barcodeService = barcodeService;
    }

    @GetMapping
    public String homePage( Model model ){
        return "redirect:/cutting/receive-inventory";
    }

    @GetMapping( "/receive-inventory" )
    public String receiveInventoryForm( Model model ){
        // 1 for cutting accounts
        model.addAttribute("accounts" , inventoryAccountService.getAllCuttingAccounts() );
        model.addAttribute("cutPieceTypes", jobCardService.getAllPieceTypes() );
        model.addAttribute("wrapper", new JobCardWrapper() );
        return "/cutting/receive-inventory";
    }

    /*
    *  get cutting inventory accounts
    * */
    @GetMapping( "/inventory-accounts" )
    public String getInventoryAccounts(  @RequestParam( value = "id", required = false ) String id,
                                         @RequestParam( value = "title", required = false) String title,
                                         @RequestParam( value = "active", required = false ) String active,
                                         @RequestParam( value = "created-by", required = false ) String createdBy,
                                         @RequestParam( value = "start-date", required = false ) String startDate,
                                         @RequestParam( value = "end-date", required = false ) String endDate,
                                         @RequestParam( value = "site-id", required = false ) String siteId,
                                         @RequestParam( value = "count", required = false ) Long count,
                                         Model model ){
        if(StringUtils.isNullOrEmpty( active )){
            return "redirect:/cutting/inventory-accounts?id=&title=&active=1&created-by=&start-date=&end-date=&site-id=&site-title=&count=100";
        }
        model.addAttribute("accounts", inventoryAccountService.getInventoryAccounts( id, title, active, createdBy, startDate, endDate, siteId, count , "PROCESS", "1", false) );
        model.addAttribute("locations", locationService.findAll() );
        return "/cutting/inventory-accounts";
    }

    @PostMapping( "/receive-inventory" )
    public String receiveInventoryToCuttingAccount(Model model,
                                                   RedirectAttributes redirectAttributes,
                                                   @RequestParam( "job-card-id" ) long jobCardId,
                                                   @ModelAttribute JobCardWrapper wrapper ){
        try {
           inventoryService.receiveJobCardInventory( jobCardId, wrapper );
            redirectAttributes.addFlashAttribute("success", "Inventory Successfully Received by Job Card  ID:  " +jobCardId );
        } catch ( Exception ex ){
            redirectAttributes.addFlashAttribute("error", ex.getMessage() );
        }
        return "redirect:/cutting/receive-inventory";
    }




    @GetMapping( "/generate-master-barcode" )
    public String showMasterBundleForm( Model model ){
        model.addAttribute("wrapper", new BundleWrapper() );
        return "/cutting/generate-master-barcode";
    }

    @PostMapping( "/generate-master-barcode" )
    public String generateMasterBarcode( @ModelAttribute BundleWrapper wrapper,
                                         RedirectAttributes redirectAttributes,
                                         Model model ){
       try {
           long id = bundleService.createMasterBundle( wrapper );
           redirectAttributes.addFlashAttribute("success", "Successfully Created Master Bundle : " + id );
       } catch ( Exception e ){
            redirectAttributes.addFlashAttribute("error", e.getMessage() );
       }
        return "redirect:/cutting/generate-master-barcode";
    }

    @GetMapping( "/bundles" )
    public String showBundles(  @RequestParam( value = "id", required = false ) String id,
                                @RequestParam( value = "sku", required = false) String sku,
                                @RequestParam( value = "jc-id", required = false) String jobCardId,
                                @RequestParam( value =  "master-id" , required = false ) String masterId,
                                @RequestParam( value = "type", required = false) String type,
                                @RequestParam( value = "status", required = false) String status,
                                @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(30) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        model.addAttribute("bundles", bundleService.getBundles( id, sku, jobCardId, masterId, type, status, startDate1.toString(), endDate1.toString() ,count ) );
        model.addAttribute("types", jobCardService.getAllPieceTypes() );
        return "/cutting/bundles";
    }

    @GetMapping( "/master-bundles")
    public String showMasterBundles( @RequestParam(value = "id" , required = false) String id,
                                     @RequestParam(value = "jc-id", required = false ) String jobCardId,
                                     @RequestParam(value = "sku", required = false ) String sku,
                                     @RequestParam(value = "status", required = false ) String status,
                                     @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(30) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        model.addAttribute("masterBundles", bundleService.getMasterBundles( id, sku, status, jobCardId, startDate1.toString(), endDate1.toString(), count ) );
        return "/cutting/master-bundles";
    }

    @GetMapping( "/get-child-bundles" )
    public String showBundlesFromMaster( @RequestParam( "master-id" ) long masterId ,
                                         Model model ){
        model.addAttribute("bundles", bundleService.findBundlesByMasterId( masterId ));
        return "/cutting/child-bundles";
    }

    @PostMapping( "/generate-bundle-barcodes" )
    public Object generateBundleBarcode(@RequestParam( name = "ids", required = false ) Long[] ids,
                                  @RequestParam( name = "artifactType", required = true ) String artifactType , RedirectAttributes redirectAttributes) throws Exception {
        if(ids == null){
            redirectAttributes.addFlashAttribute("error", "Please Select At least One CheckBox." );
            return "redirect:/cutting/bundles";
        }
        try {
            barcodeService.generateBarcodes( Arrays.asList( ids ), artifactType );
            redirectAttributes.addFlashAttribute( "success", "Barcode generated successfully" );
            return "redirect:/cutting/bundles";
        }catch (Exception e){
            redirectAttributes.addFlashAttribute( "error", e );
            return "redirect:/cutting/bundles";
        }
    }

    @PostMapping( "/generate-master-barcodes" )
    public Object generateMasterBarcode(@RequestParam( name = "ids", required = false ) Long[] ids,
                                  @RequestParam( name = "artifactType", required = true ) String artifactType, RedirectAttributes redirectAttributes ) throws Exception {
        if(ids == null){
            redirectAttributes.addFlashAttribute("error", "Please Select At least One CheckBox." );
            return "redirect:/cutting/master-bundles";
        }
        try {
            barcodeService.generateBarcodes( Arrays.asList( ids ), artifactType );
            redirectAttributes.addFlashAttribute( "success", "Master barcode generated successfully" );
            return "redirect:/cutting/master-bundles";
        }catch (Exception e){
            redirectAttributes.addFlashAttribute( "error", e );
            return "redirect:/cutting/master-bundles";
        }
    }

    @PostMapping( "/generate-qrCode" )
    public Object generateBarcode(@RequestParam( name = "ids" ,required = false) Long[] ids,
                                  @RequestParam( name = "artifactType"  ) String artifactType, RedirectAttributes redirectAttributes ) throws Exception {
        if (ids == null){
            redirectAttributes.addFlashAttribute( "error", "Select At least One CheckBox" );
            return "redirect:/cutting/cutting-items";        }
        try {
            barcodeService.generateBarcodes( Arrays.asList( ids ), artifactType );
            redirectAttributes.addFlashAttribute( "success", "Barcode generated successfully" );
            return "redirect:/cutting/cutting-items";
        }catch (Exception e){
            redirectAttributes.addFlashAttribute( "error", e );
            return "redirect:/cutting/cutting-items";        }
    }

    /*
     * get finished items
     * */
    @GetMapping( "/cutting-items" )
    public String getStitchingOfflineItems( @RequestParam(value = "id", required = false ) String id,
                                            @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,
                                            @RequestParam(value = "bundle-id", required = false) Long bundleId,
                                            @RequestParam( value = "count", required = false, defaultValue = "100") Long count,
                                            @RequestParam( value = "status", required = false) String status,
                                            Model model, RedirectAttributes redirect){
        LocalDate startDate1 = StringUtils.isNullOrEmpty(startDate) ? LocalDate.now().minusDays(30) : LocalDate.parse(startDate);
        LocalDate endDate1 = StringUtils.isNullOrEmpty(endDate) ? LocalDate.now() : LocalDate.parse(endDate);
        List<StitchingOfflineItem> itemList = bundleService.getStitchedOfflineItems( id, itemId, sku, status, startDate, endDate, bundleId, count );
        model.addAttribute("items", itemList ) ;
        model.addAttribute("startDate", startDate1);
        model.addAttribute("endDate", endDate1);
        return "/stitching/stitched-offline-items";
    }
}
