package com.utopiaindustries.service;

import com.utopiaindustries.dao.ctp.*;
import com.utopiaindustries.model.ctp.Bundle;
import com.utopiaindustries.model.ctp.FinishedItem;
import com.utopiaindustries.model.ctp.MasterBundle;
import com.utopiaindustries.model.ctp.StitchingOfflineItem;
import com.utopiaindustries.querybuilder.ctp.BundleQueryBuilder;
import com.utopiaindustries.querybuilder.ctp.FinishedItemQueryBuilder;
import com.utopiaindustries.querybuilder.ctp.MasterBundleQueryBuilder;
import com.utopiaindustries.querybuilder.ctp.StichedOfflineItemQueryBuilder;
import com.utopiaindustries.util.NumberUtils;
import com.utopiaindustries.util.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class BundleService {

    private final BundleDAO bundleDAO;
    private  final MasterBundleDAO masterBundleDAO;
    private final CryptographyService cryptographyService;
    private final FinishedItemDAO finishedItemDAO;
    private final StitchingOfflineItemDAO stitchingOfflineItemDAO;

    public BundleService(BundleDAO bundleDAO, MasterBundleDAO masterBundleDAO, CryptographyService cryptographyService, FinishedItemDAO finishedItemDAO, StitchingOfflineItemDAO stitchingOfflineItemDAO) {
        this.bundleDAO = bundleDAO;
        this.masterBundleDAO = masterBundleDAO;
        this.cryptographyService = cryptographyService;
        this.finishedItemDAO = finishedItemDAO;
        this.stitchingOfflineItemDAO = stitchingOfflineItemDAO;
    }

    /*
    * find bundles by params
    * */
    public List<Bundle> getBundles( String id, String sku, String jobCardId, String masterId,String type, String status, String startDate, String endDate, Long count ){
        List<Bundle> bundles = new ArrayList<>();
        if( count == null ){
            count = 100L;
        }
        if( StringUtils.isAnyNotNullOrEmpty( id, sku, jobCardId, masterId, type, status, startDate, endDate ) ){
            String query = BundleQueryBuilder.buildQuery( id, sku, jobCardId, masterId, type, status, startDate, endDate , count );
            System.out.println( query );
            bundles =  bundleDAO.findByQuery( query );
        } else {
            bundles = bundleDAO.findByLimit( count );
        }
        return bundles;
    }

    /*
    *  find master bundles by params
    * */
    public List<MasterBundle> getMasterBundles( String id, String jobCardId, String startDate, String endDate, Long count ){
        List<MasterBundle> bundles = new ArrayList<>();
        if( count == null ){
            count = 100L;
        }
        if( StringUtils.isAnyNotNullOrEmpty(id, jobCardId, startDate, endDate ) ){
            String query = MasterBundleQueryBuilder.buildQuery( id, jobCardId, startDate, endDate , count );
            System.out.println( query );
            bundles = masterBundleDAO.findByQuery( query );
        } else {
            bundles = masterBundleDAO.findByLimit( count );
        }
        return bundles;
    }

    /*
    * find finished Items by params
    * */
    public List<FinishedItem> getFinishedItem(String id, String itemId, String sku, String createdStartDate, String createdEndDate, String jobCardId, Long count ){
        List<FinishedItem> finishedItems = new ArrayList<>();
        if( count == null ){
            count = 100L;
        }
        if( StringUtils.isAnyNotNullOrEmpty(id, itemId, sku, createdStartDate, createdEndDate, jobCardId ) ){
            String query = FinishedItemQueryBuilder.buildQuery( id, itemId, sku, createdStartDate, createdEndDate, jobCardId , count );
            System.out.println( query );
            finishedItems = finishedItemDAO.findByQuery( query );
        } else {
            finishedItems = finishedItemDAO.findByLimit( count );
        }
        return finishedItems;
    }


    /*
     * find finished Items by params
     * */
    public List<StitchingOfflineItem> getStitchedOfflineItems(String id, String itemId, String sku, String createdStartDate, String createdEndDate, String jobCardId, Long count ){
        List<StitchingOfflineItem> stitchingOfflineItems = new ArrayList<>();
        if( count == null ){
            count = 100L;
        }
        if( StringUtils.isAnyNotNullOrEmpty(id, itemId, sku, createdStartDate, createdEndDate, jobCardId ) ){
            String query = StichedOfflineItemQueryBuilder.buildQuery( id, itemId, sku, createdStartDate, createdEndDate, jobCardId , count );
            System.out.println( query );
            stitchingOfflineItems = stitchingOfflineItemDAO.findByQuery( query );
        } else {
            stitchingOfflineItems = stitchingOfflineItemDAO.findByLimit( count );
        }
        return stitchingOfflineItems;
    }


    /*
    *
    * */
    public List<Bundle> getBundleByIdAndItemIdAndSku( String term ){
        return bundleDAO.findByTerm( term );
    }

    /**
     * */
    public List<MasterBundle> getMasterBundleByIdTerm( String term, boolean isReceived ){ return masterBundleDAO.findByTermAndNotReceived( term , isReceived);}

    /*
    * create master bundle and tag to child bundles
    * */
    public long createMasterBundle( BundleWrapper wrapper ){
        if( wrapper != null && wrapper.getBundles() != null && ! wrapper.getBundles().isEmpty() ){
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            long itemId = 0;
            String sku = "";
            long jobCardId = 0;
            MasterBundle masterBundle = new MasterBundle();
            masterBundle.setCreatedBy(  authentication.getName() );
            masterBundle.setCreatedAt( LocalDateTime.now() );
            long id = masterBundleDAO.save( masterBundle );
            masterBundle.setId( id );
            masterBundle.setBarcode( cryptographyService.generateRandomString( 15 ) );
            List<Bundle> newBundles = new ArrayList<>();
            for( Bundle bundle : wrapper.getBundles() ){
                bundle.setMasterBundleId( id  );
                newBundles.add( bundle );
                // sku and item in master bundle
                if( StringUtils.isNullOrEmpty( sku ) ){
                    sku = bundle.getSku();
                }
                if( NumberUtils.isNullOrZero( itemId ) ) {
                    itemId = bundle.getItemId();
                }
                if( NumberUtils.isNullOrZero( jobCardId ) ){
                    jobCardId = bundle.getJobCardId();
                }
            }
            masterBundle.setItemId( itemId );
            masterBundle.setSku( sku );
            masterBundle.setJobCardId( jobCardId );
            // save master
            masterBundleDAO.save( masterBundle );
            //save child bundles
            bundleDAO.saveAll( newBundles );
            return id;
        }
        return 0;
    }

    /*
    *  find by master id
    * */
    public List<Bundle> findBundlesByMasterId( long masterId ){
        return bundleDAO.findByMasterId( masterId );
    }

}
