package com.utopiaindustries.controller;

import com.utopiaindustries.auth.JobCardRole;
import com.utopiaindustries.dao.ctp.JobCardDAO;
import com.utopiaindustries.model.ctp.JobCard;
import com.utopiaindustries.model.ctp.JobCardItem;
import com.utopiaindustries.service.InventoryAccountService;
import com.utopiaindustries.service.JobCardService;
import com.utopiaindustries.service.LocationService;
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.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@JobCardRole
@RequestMapping( "/job-cards" )
public class JobCardController {

    private final JobCardService jobCardService;
    private final LocationService locationService;
    private final InventoryAccountService inventoryAccountService;
    private final JobCardDAO jobCardDAO;

    public JobCardController(JobCardService jobCardService, LocationService locationService, InventoryAccountService inventoryAccountService, JobCardDAO jobCardDAO){
        this.jobCardService = jobCardService;
        this.locationService = locationService;
        this.inventoryAccountService = inventoryAccountService;
        this.jobCardDAO = jobCardDAO;
    }

    /**
     *  get all job cards
     * */
    @GetMapping
    public String showJobCardList(  @RequestParam( value = "code", required = false ) String code,
                                    @RequestParam( value = "status", required = false ) String status,
                                    @RequestParam( value = "inventory-status" , required = false) String inventoryStatus,
                                    @RequestParam( value = "customer" ,required = false ) String customer,
                                    @RequestParam( value = "lot-number", required = false ) String lotNumber,
                                    @RequestParam( value = "purchase-order-id", required = false ) String purchaseOrderId,
                                    @RequestParam( value = "site-id", required = false ) String locationSiteId,
                                    @RequestParam( value = "created-start-date", required = false ) String createdStartDate,
                                    @RequestParam( value = "created-end-date", required = false ) String createdEndDate,
                                    @RequestParam( value = "limit" , required = false) Long limit,
                                    Model model ){

        LocalDate startDate = StringUtils.isNullOrEmpty(createdStartDate) ? LocalDate.now().minusDays(30) : LocalDate.parse(createdStartDate);
        LocalDate endDate = StringUtils.isNullOrEmpty(createdEndDate) ? LocalDate.now() : LocalDate.parse(createdEndDate);
        String code1 = StringUtils.isNullOrEmpty(code) ? "" : code;
        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);
        List<JobCard> cards = jobCardService.getCards(code1, status, inventoryStatus, customer, lotNumber, purchaseOrderId, locationSiteId,startDate.toString(), endDate.toString(), limit );
        model.addAttribute("cards", cards );
        model.addAttribute("statuses", JobCard.Status.values() );
        model.addAttribute("invStatuses", JobCard.InventoryStatus.values() );
        model.addAttribute("locations", locationService.findAll() );
        return "job-card-list";
    }

    @GetMapping( "/new" )
    public String showJobCardForm( Model model ){
        model.addAttribute("jobCard", jobCardService.createNewJobCard() );
        model.addAttribute("cutPieceTypes", jobCardService.getAllPieceTypes() );
        model.addAttribute("accounts", inventoryAccountService.getAllCuttingAccounts( ) );
        return "job-card-add";
    }

    @GetMapping( value = "/edit/{id}" )
    public String showJobCardEditForm( @PathVariable("id") long id,
                                       Model model ){
        model.addAttribute("jobCard", jobCardService.findCardRecursivelyForView( id ) );
        model.addAttribute("cutPieceTypes", jobCardService.getAllPieceTypes() );
        model.addAttribute("accounts", inventoryAccountService.getAllCuttingAccounts() );
        return "job-card-edit";
    }

    /*
    *  draft
    * */
    @PostMapping( value ="/edit" , params = "user=draft" )
    public String saveJobCard( @ModelAttribute JobCard jobCard,
                               RedirectAttributes redirectAttributes,
                               Model model ){
        try {
            jobCard.setStatus( JobCard.Status.DRAFT.name() );
            jobCard.setInventoryStatus( JobCard.InventoryStatus.NOT_RECEIVED_YET.name() );
            jobCardService.save( jobCard );
           redirectAttributes.addFlashAttribute("success", "Successfully saved!" );
        } catch ( Exception ex ){
            redirectAttributes.addFlashAttribute("error", ex.getMessage() );
        }
        return "redirect:/job-cards";
    }

    /*
    *  draft after save
    * */
    @PostMapping( value ="/edit/{id}" , params = "user=draft" )
    public String saveJobCardEdit( @ModelAttribute JobCard jobCard,
                                   @PathVariable long id,
                                   RedirectAttributes redirectAttributes,
                                   Model model ){

        try {
            jobCard.setStatus( JobCard.Status.DRAFT.name() );
            jobCard.setInventoryStatus( JobCard.InventoryStatus.NOT_RECEIVED_YET.name() );
            jobCardService.save( jobCard );
            redirectAttributes.addFlashAttribute("success", "Successfully saved!" );
        } catch ( Exception ex ){
            redirectAttributes.addFlashAttribute("error", ex.getMessage() );
        }
        return "redirect:/job-cards";
    }

    @PostMapping( value ="/edit" , params = "user=post" )
    public String postJobCard( @ModelAttribute JobCard jobCard,
                               RedirectAttributes redirectAttributes,
                               Model model ){

        try {
            jobCard.setStatus(JobCard.Status.POSTED.name() );
            jobCardService.save( jobCard );
            redirectAttributes.addFlashAttribute("success", "Successfully saved!" );
        } catch ( Exception ex ){
            redirectAttributes.addFlashAttribute("error", ex.getMessage() );
        }
        return "redirect:/job-cards";
    }


    /*
    * post after draft
    * */
    @PostMapping( value ="/edit/{id}" , params = "user=post" )
    public String postJobCardEdit( @ModelAttribute JobCard jobCard,
                                   @PathVariable long id,
                                   RedirectAttributes redirectAttributes,
                                   Model model ){
        try {
            jobCard.setStatus(JobCard.Status.POSTED.name() );
            jobCardService.save( jobCard );
            redirectAttributes.addFlashAttribute("success", "Successfully saved!" );
        } catch ( Exception ex ){
            redirectAttributes.addFlashAttribute("error", ex.getMessage() );
        }
        return "redirect:/job-cards";
    }

    @GetMapping( value = "/view/{id}" )
    public String showJobCardDetail( @PathVariable("id") long id,
                                       Model model ){
        List<JobCardItem> jobCardItems = jobCardService.findJobCardItemByJobCardId(id);
        List<Long> jobCardItemIds = jobCardItems.stream()
                .map(JobCardItem::getItemId)
                .collect(Collectors.toList());
        List<Long> itemIds = jobCardItems.stream()
                .map(JobCardItem::getId)
                .collect(Collectors.toList());
        model.addAttribute( "card", jobCardService.findByID(id));
        model.addAttribute("jobCardItems", jobCardItems);
        model.addAttribute("cutPiece",jobCardService.findCutPieceByJobCardItemIds(itemIds));
        model.addAttribute("finishItem",jobCardService.findFinishItemByJobCardId(id));
        model.addAttribute("stitchingItem",jobCardService.findStitchItemByJobCardId(id));
        model.addAttribute("totalFinishItem",jobCardService.totalFinishItem(jobCardItemIds, id));
        model.addAttribute("totalStitchingItem",jobCardService.totalStitchingItem(jobCardItemIds, id));
        return "job-card-view";
    }

    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;
    }
}
