<?php

namespace App\Http\Controllers\Service;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Helpers\HelperController;
use App\Models\Current_team;
use App\Models\Location;
use App\Models\Location_clerks;
use App\Models\Material;
use App\Models\Material_group;
use App\Models\Material_type;
use App\Models\Plant;
use App\Models\Stage;
use App\Models\Stock_take;
use App\Models\Stock_take_material;
use Brian2694\Toastr\Facades\Toastr;
use Carbon\Laravel\ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class ServiceController extends Controller
{
    /**
     * Method get_plants
     *
     * @return void
     */
    static public function get_plants()
    {
        $user = Auth::user();
        $url = "196.41.87.26/stock-take-test/plants";
        $token = $user->token;
        return HelperController::auth_http_get_request($url, $token);
        // $response =  HelperController::auth_http_get_request($url, $token);
    }

    /**
     * Method get_locations
     *
     * @param $plant_code $plant_code [explicite description]
     *
     * @return void
     */
    static public function get_locations($plant_code)
    {
        $user = Auth::user();
        $url = '196.41.87.26/stock-take-test/storage-locations?plant_code=' . $plant_code;
        $token = $user->token;
        return HelperController::auth_http_get_request($url, $token);
    }

    /**
     * Method save_plants
     *
     * @param $plants $plants [explicite description]
     *
     * @return void
     */
    static public function save_plants($plants)
    {
        //check if exist and update
        foreach ($plants as $key => $plant) {
            if (substr($plant->plant_code, 0, 1) == 2) {
                $company_code = 2000;
            } else if (substr($plant->plant_code, 0, 1) == 1) {
                $company_code = 1000;
            } else {
                $company_code = "";
            }
            $check = Plant::where('plant_code', $plant->plant_code)->first();
            if ($check) {
                $check->update(array_merge((array)$plant, ['company_code' => $company_code]));
            } else {
                Plant::create(array_merge((array)$plant, ['company_code' => $company_code]));
            }
        }

        //save 
    }

    /**
     * Method save_locations
     *
     * @param $locations $locations [explicite description]
     * @param $plant_code $plant_code [explicite description]
     *
     * @return void
     */
    static public function save_locations($locations, $plant_code)
    {
        // $locations_1 = array(); 

        foreach ($locations as $key => $location) {
            // $locations_1[] = $location;
            $check = Location::where('storage_location_code', $location->storage_location_code)->first();
            if ($check) {

                $check->storage_location_code = $location->storage_location_code;
                $check->storage_location_name = $location->storage_location_name;
                $check->plant_code = $plant_code;
                $check->save();
                // $check->update(array_merge((array)$location, ['plant_code' => $plant_code]));
            } else {

                $loc = new Location();
                $loc->storage_location_code = $location->storage_location_code;
                $loc->storage_location_name = $location->storage_location_name;
                $loc->plant_code = $plant_code;
                $loc->save();
                // Location::create(array_merge((array)$location, ['plant_code' => $plant_code]));
            }
        }

        return Location::where('plant_code', $plant_code)->get();
        
    }

    /**
     * Method save_materials
     *
     * @param $header $header [explicite description]
     * @param $materials $materials [explicite description]
     *
     * @return void
     */
    static public function save_materials($header, $materials)
    {
        foreach ($materials as $key => $material) {
            //check if exist
            $check = Material::where('material_no', $material->material_no)->first();
            $data = [
                'plant_code' => $header->plant_code,
                'storage_location_code' => $header->storage_location_code,
                'item_id' => $material->item_id,
                'material_name' => $material->material_name,
                'material_no' => $material->material_no,
                'unit_of_measure' => $material->unit_of_measure,
                'sap_stock' => $material->closing_stock,
                'material_type_code' => $material->material_type_code,
                'material_group_code' => $material->material_group_code
            ];
            if (!$check) {
                Material::create(array_merge($data));
            } else {
                $check->update(array_merge($data));
            }
        }
    }

    //save current stock if first time

    /**
     * Method save_current_stock
     *
     * @param $material_no $material_no [explicite description]
     * @param $current_stock $current_stock [explicite description]
     * @param $location_code $location_code [explicite description]
     * @param $proposed_date $proposed_date [explicite description]
     *
     * @return void
     */
    static public function save_current_stock($material_no, $current_stock, $id, $team)
    {
        foreach ($material_no as $key => $material) {
            $stock = $current_stock[$key];
            $mat = Stock_take_material::where([['stock_take_id', $id], ['material_no', $material]])->first();

            //save data to respective group result 
            $team == "A"? $mat->update(['team_A_result' => $stock]) : $mat->update(['team_B_result' => $stock]);            
        }
        ServiceController::update_team($id);
    }

    //if sum of local variance is 0 stock take is closed    
    /**
     * Method check_stock_take_closure
     *
     * @param $material_no $material_no [explicite description]
     * @param $current_stock $current_stock [explicite description]
     * @param $location_code $location_code [explicite description]
     * @param $proposed_date $proposed_date [explicite description]
     *
     * @return void
     */
    static public function check_stock_take_closure($material_no, $current_stock, $id)
    {
        $local_sum = Stock_take_material::where('stock_take_id', $id)->get()->sum('local_variance');
        $sap_sum = Stock_take_material::where('stock_take_id', $id)->get()->sum('sap_variance');
        $state = Stock_take::where('id', $id)->first();
        if ($state && $state->counting_status == 'closed') {
            return back()->with('danger', 'Stock take for this location is already closed');
        } else {
            ServiceController::update_and_save_current_stock($material_no, $current_stock, $id);
            $process = ServiceController::sum_and_compare_variance($material_no, $current_stock, $id);
            if ($process === 'repeat') {
                //update team
                ServiceController::update_team($id);
                HelperController::reset_after_variance($id);
                return back()->with('danger', 'Variance established kindly repeat stock take');
            } else {
                $state->update(['counting_status' => 'closed']);
                ServiceController::stage_update($id);
                HelperController::clear_counting_record($id);
                Toastr::success('Stock saved successfully. No variance established and marks closure of stock take on this location!', 'Success');
                return back();
            }
        }
    }

    //update and save current stock    
    /**
     * Method update_and_save_current_stock
     *
     * @param $material_no $material_no [explicite description]
     * @param $current_stock $current_stock [explicite description]
     * @param $location_code $location_code [explicite description]
     * @param $proposed_date $proposed_date [explicite description]
     *
     * @return void
     */
    static public function update_and_save_current_stock($material_no, $current_stock, $id)
    {
        foreach ($material_no as $key => $material) {
            $new_stock = $current_stock[$key];
            $mat = Stock_take_material::where([['stock_take_id', $id], ['material_no', $material]])->first();
            $local_variance = ServiceController::calculate_local_variance($mat->current_stock, $new_stock);
            $mat->update(['current_stock' => $new_stock, 'local_variance' => $local_variance]);
        }
    }

    //calculate local variance    
    /**
     * Method calculate_local_variance
     *
     * @param $current_stock $current_stock [explicite description]
     * @param $new_stock $new_stock [explicite description]
     *
     * @return void
     */
    static public function calculate_local_variance($current_stock, $new_stock)
    {
        return ($new_stock) - ($current_stock);;
    }

    //check local variance sum    
    /**
     * Method sum_and_compare_variance
     *
     * @param $material_no $material_no [explicite description]
     * @param $current_stock $current_stock [explicite description]
     * @param $location_code $location_code [explicite description]
     * @param $proposed_date $proposed_date [explicite description]
     *
     * @return void
     */
    static public function sum_and_compare_variance($material_no, $current_stock, $id)
    {
        $sum = Stock_take_material::where('stock_take_id', $id)->get()->sum('local_variance');
        switch ($sum) {
            case 0:

                //get all the materials data
                $stock_count_results = Stock_take_material::where('stock_take_id', $id)->get();

                //update current stock if no variance established
                //update sap variance
                foreach ($stock_count_results as $data) {
                
                    $current_stock = $data->team_A_result;

                    //update current stock
                    Stock_take_material::where([['stock_take_id', $id], ['material_no', $data->material_no]])->update(['current_stock' => $current_stock]);

                    //update SAP variance
                    $mat = Stock_take_material::where([['stock_take_id', $id], ['material_no', $data->material_no]])->first();
                    ServiceController::update_sap_variance($mat, $mat->current_stock, $mat->sap_stock);
                
                }

                # code...
                # update sap variance
                // foreach ($material_no as $key => $material) {
                //     $mat = Stock_take_material::where([['stock_take_id', $id], ['material_no', $material]])->first();
                //     ServiceController::update_sap_variance($mat, $mat->current_stock, $mat->sap_stock);
                // }
                break;

            default:
                $state = Stock_take::where('id', $id)->first();
                $state->update(['counting_status' => 'repeat']);
                return 'repeat';
                break;
        }
    }

    //update sap variance if local valiance sum is 0    
    /**
     * Method update_sap_variance
     *
     * @param $mat $mat [explicite description]
     * @param $current_stock $current_stock [explicite description]
     * @param $sap_stock $sap_stock [explicite description]
     *
     * @return void
     */
    static public function update_sap_variance($mat, $current_stock, $sap_stock)
    {
        $sap_variance = ServiceController::calculate_sap_variance($current_stock, $sap_stock);
        $mat->update(['sap_variance' => $sap_variance]);
    }

    //calculate sap variance    
    /**
     * Method calculate_sap_variance
     *
     * @param $current_stock $current_stock [explicite description]
     * @param $sap_stock $sap_stock [explicite description]
     *
     * @return void
     */
    static public function calculate_sap_variance($current_stock, $sap_stock)
    {
        return ($current_stock) - ($sap_stock);
    }

    /**
     * Method save_material_types
     *
     * @param $types $types [explicite description]
     *
     * @return void
     */
    static public function save_material_types($types)
    {
        foreach ($types as $key => $type) {
            $data = [
                'material_type_code' => $type->material_type_code,
                'material_type_name' => $type->material_type_name,
            ];
            $check = Material_type::where('material_type_code', $type->material_type_code)->first();
            if ($check) {
                $check->update(array_merge($data));
            } else {
                Material_type::create(array_merge($data));
            }
        }
    }

    /**
     * Method save_material_groups
     *
     * @param $groups $groups [explicite description]
     *
     * @return void
     */
    static public function save_material_groups($groups)
    {
        foreach ($groups as $key => $group) {
            $data = [
                'material_group_code' => $group->material_group_code,
                'material_group_name' => $group->material_group_name,
            ];
            $check = Material_group::where('material_group_code', $group->material_group_code)->first();
            if ($check) {
                $check->update(array_merge($data));
            } else {
                Material_group::create(array_merge($data));
            }
        }
    }

    static public function update_team($id)
    {
        $user = Auth::user();
        $team = Location_clerks::where([['user_id', $user->id], ['status', 'active'], ['stock_take_id', $id]])->first();

        $data = [
            'stock_take_id' => $id,
            'team' => $team->team,
        ];
        if ($team) {
            $check = Current_team::where('stock_take_id', $id)->first();
            if ($check && $check->team !== $team->team) {
                $check->update(array_merge($data));
            } else {
                Current_team::create($data);
            }
        }
    }

    static public function stage_update($id)
    {
        $check = Stock_take::where('id', $id)->first();
        $plant_code = $check->plant_code;
        $confirm = Stock_take::where([['plant_code', $plant_code], ['counting_status', '!=', 'closed']])->whereNotNull('doc_no')->get();
        if (count($confirm) > 0) {
            #Do nothing
        } else {
            $stage = Stage::where([['plant_code', $plant_code], ['status', 'active']])->first();
            $stage->update(['level' => 'Storage Supervisor']);
        }
    }
}