<?php
namespace process;

use FilesystemIterator;
use Workerman\Timer;
use support\Db;
use support\Log;
use support\ApiTask;

class TaskGetPdm
{
    private $task;
    private $limit = 30;
    public function onWorkerStart()
    {
        $this->task = new ApiTask('api_pdm');
		$data = $this->task->get();
		if(empty($data->access_time)){
		    //首次执行，一般测试用
            Timer::add(5, function(){
                $data = $this->task->get();
                $this->execute($data);
            },[],false);
		}
        // 每隔 1 小时检查一次
        // 执行一次大概 15 * 2 = 30分钟
        //Timer::add(3600, function(){
        Timer::add(120, function(){
    		$data = $this->task->get();
    		if($data->enable 
    		   && time()>strtotime($data->begin_start_time) //开始时间
    		   && (empty($data->access_time) || time()-strtotime($data->access_time) > $data->interval)
    		){
                $nowTime = getNowTime();
                if($data->interval >= 86400){ //达到或超过1天时
                    $t = explode(' ',$data->begin_start_time); 
                    $jgTime = $t[1];
                    $t = explode(' ',getNowTime()); 
                    $date = $t[0];
                    $nowTime  = $date .' '. $jgTime;
                }
                if ($data->complete_status == 1) {
    			    $this->task->begin($nowTime);
                }
    		    $this->execute($data);
                $this->task->complete(getNowTime());
       		}
        });
    }
    public function execute($data)
    {
        //DRJN 北美, T046 南美
        $meta = json_decode($data->meta,true);
        $brands = ['DRJN'=>1,'JVFW'=>1];
        if(!empty($data->error)){
            //断点续取 
            $brands[$meta['brand']] = $meta['page'];
            foreach ($brands as $brand=>$page){
                if($brand==$meta['brand']){
                    break;
                }else{
                    unset($brands[$brand]);
                }
            }
        }
        //{"page": 1, "brand": "JVFW", "limit": 50, "last_time": "2025-04-24 11:59:27"}
        $nowTime = getNowTime();
        if ($data->complete_status == 1) {
            /*
            //清空
            Db::table('api_pdm_applications')->truncate();
            Db::table('api_pdm_custom_fields')->truncate();
            Db::table('api_pdm_interchange_informations')->truncate();
            Db::table('api_pdm_items')->truncate();
            */
        }
		foreach ($brands as $brand=>$page){
    		$this->save($brand,$data->access_time,$nowTime,$page);
		}
    }
    
    public function save($brand,$beginTime,$endTime,$page=1)
    {
        try {
            $status = true;
            while($status){
                $meta = ['brand' => $brand,'page' => $page,'limit' => $this->limit,'last_time' => getNowTime()];
                $this->task->meta($meta);
                Log::channel('task_get_pdm')->info('meta:'.json_encode($meta,JSON_UNESCAPED_UNICODE));
                $data = $this->getPageData($brand,$page,$this->limit);
                if(empty($data)){
                    $status = false;
                    break;
                }else{
                    $this->SaveInterchangeInformations($data['interchange_informations']);
                    $this->SaveItems($data['items']);
                    $this->SaveCustomFields($data['custom_fields']);
                    $this->SaveApplications($data['applications']);
                }
                $page++;
            }
        } catch (Exception $e) {
            Log::channel('task_get_pdm')->info('execute() exception:'.$e->getMessage());
        }
    }

    public function getPageData($brand,$page,$limit=100,$error=0)
    {
        $send = [
			'url'=>'http://test.edi-runtime.jdl.cn/api/sap/QueryProductInfo',
			'auth'=>[
				'type'=>'BASIC',
				'username'=>'gspcpgl',
				'password'=>'sPEj3kGMfy*7!$+V'
			],
			'timeout'=>900,
			'dataType'=>'json',
			'data'=>[
				'brand_code'=>$brand,
				'segments'=>'items,applications,interchange_informations,custom fields', //custom_fields
                'use_staging_database'=>1,
				'page'=>$page,
				'limit'=>$limit
			],
		];
		$json = curl($send);
        if($json['status']){
            $data = json_decode($json['content'],true);
        }
        if(!$json['status'] || json_last_error() != JSON_ERROR_NONE ||  empty($data)){
            $this->task->error('curl:'.json_encode($json,JSON_UNESCAPED_UNICODE));
            Log::channel('task_get_pdm')->info('send:'.json_encode($send,JSON_UNESCAPED_UNICODE) . ', return:'.json_encode($json,JSON_UNESCAPED_UNICODE));
            if($error<5){
                sleep(2);
                return $this->getPageData($brand,$page,$limit,$error+1);
            } else {
                return null;
            }
        }
        
        return $data;
    }
     
    public function SaveInterchangeInformations($items)
    {
        $enableKeys = ['interchange_informations_part_number','interchange_informations_brand','interchange_informations_interchange_part_number','interchange_informations_interchange_brand','interchange_informations_interchange_brand_name','interchange_informations_quantity','interchange_informations_quantity_uom','interchange_informations_quantity_uom_description','interchange_informations_item_equivalent_uom','interchange_informations_item_equivalent_uom_description','interchange_informations_quality_grade_level_code','interchange_informations_quality_grade_level_name','interchange_informations_language_code','interchange_informations_language_name'];
        foreach($items as $item){
            $newItem = [];
            foreach($enableKeys as $enableKey){
                if(isset($item[$enableKey])){
                    $newKey = substr($enableKey,strlen('interchange_informations_'));
                    $newItem[$newKey] = $item[$enableKey];
                }
            }
			$row = Db::table('api_pdm_interchange_informations')
					->where([
					    ['brand',$newItem['brand']],
					    ['part_number',$newItem['part_number']],
					    ['interchange_brand',$newItem['interchange_brand']],
					    ['interchange_part_number',$newItem['interchange_part_number']],
					])
					->first();
			if(!empty($row)){
				Db::table('api_pdm_interchange_informations')
					->updateOrInsert(
						[
						    'brand'=>$newItem['brand'],
						    'part_number'=>$newItem['part_number'],
						    'interchange_brand'=>$newItem['interchange_brand'],
						    'interchange_part_number'=>$newItem['interchange_part_number'],
						],
						$newItem
					);
			}else{
				Db::table('api_pdm_interchange_informations')->insertOrIgnore($newItem);
			}
            
        }
    }
    
    public function SaveCustomFields($items)
    {
        $enableKeys = ['custom_fields_part_number','custom_fields_brand','custom_fields_vio count'];
        foreach($items as $item){
            $newItem = [];
            foreach($enableKeys as $enableKey){
                if(isset($item[$enableKey])){
                    $newKey = substr($enableKey,strlen('custom_fields_'));
                    $newKey = str_replace(' ','_',$newKey);
                    $newItem[$newKey] = $item[$enableKey];
                }
            }
			$row = Db::table('api_pdm_custom_fields')
					->where([
					    ['brand',$newItem['brand']],
					    ['part_number',$newItem['part_number']],
					])
					->first();
			if(!empty($row)){
				Db::table('api_pdm_custom_fields')
					->updateOrInsert(
						[
						    'brand'=>$newItem['brand'],
						    'part_number'=>$newItem['part_number'],
						],
						$newItem
					);
			}else{
				Db::table('api_pdm_custom_fields')->insertOrIgnore($newItem);
			}
            
        }
    }
     
    public function SaveItems($items)
    {
        $enableKeys = ['items_part_number','items_brand','items_brand_label','items_title','items_application_summary','items_population_status','items_part_type','items_sub_category','items_category','items_part_terminology_id','items_hazardous_material','items_aces_application','items_universal_part','items_gtin','items_gtin_qualifier_code','items_gtin_qualifier_name','items_quantity_size','items_quantity_size_uom','items_container_type','items_quantity_per_application','items_quantity_per_application_uom','items_quantity_per_application_qualifier','items_minimum_order_quantity','items_minimum_order_quantity_uom','items_part_group','items_default_mfr_label','items_default_application_qty','items_tags','items_position','items_vmrs_code','items_unspsc','items_part_category_code','items_part_sub_group','items_effective_date','items_available_date','items_base_part_number','items_sub_brand'];
        foreach($items as $item){
            $newItem = [];
            foreach($enableKeys as $enableKey){
                if(isset($item[$enableKey])){
                    $newKey = substr($enableKey,strlen('items_'));
                    $newItem[$newKey] = $item[$enableKey];
                }
            }
			$row = Db::table('api_pdm_items')
					->where([
					    ['brand',$newItem['brand']],
					    ['part_number',$newItem['part_number']],
					])
					->first();
			if(!empty($row)){
				Db::table('api_pdm_items')
					->updateOrInsert(
						['brand'=>$newItem['brand'],'part_number'=>$newItem['part_number']],
						$newItem
					);
			}else{
				Db::table('api_pdm_items')->insertOrIgnore($newItem);
			}
            
        }
    }
   
    public function SaveApplications($items)
    {
        $enableKeys = [ 'applications_app_id',
                        'applications_brand',
                        'applications_part_number',
                        'applications_qty',
                        'applications_display_order',
                        'applications_mfr_label',
                        'applications_part_type',
                        'applications_make',
                        'applications_model',
                        'applications_sub_model',
                        'applications_year_from',
                        'applications_year_to',
                        'applications_drive',
                        'applications_position',
                        'applications_region',
                        'applications_base_model_type',
                        'applications_bed_length',
                        'applications_bed_type',
                        'applications_body_door',
                        'applications_body_type',
                        'applications_brake_abs',
                        'applications_brake_system',
                        'applications_engine_aspiration',
                        'applications_engine_base_block_type',
                        'applications_engine_base_bore_inch',
                        'applications_engine_base_bore_metric',
                        'applications_engine_base_cubic_centimeter',
                        'applications_engine_base_cubic_inch',
                        'applications_engine_base_cylinder',
                        'applications_engine_base_liter',
                        'applications_engine_base_stroke_inch',
                        'applications_engine_base_stroke_metric',
                        'applications_engine_cylinder_head_type',
                        'applications_engine_designation',
                        'applications_engine_fuel_delivery_sub_type',
                        'applications_engine_fuel_delivery_system_control_type',
                        'applications_engine_fuel_delivery_system_design',
                        'applications_engine_fuel_delivery_type',
                        'applications_engine_fuel_type',
                        'applications_engine_ignition_system_type',
                        'applications_engine_mfr',
                        'applications_engine_power_output',
                        'applications_engine_valve',
                        'applications_engine_version',
                        'applications_engine_vin',
                        'applications_front_brake_type',
                        'applications_front_spring_type',
                        'applications_mfr_body_code',
                        'applications_rear_brake_type',
                        'applications_rear_spring_type',
                        'applications_steering_system',
                        'applications_steering_type',
                        'applications_transmission_base_control_type',
                        'applications_transmission_base_gear',
                        'applications_transmission_base_type',
                        'applications_transmission_electronocially_controlled_information',
                        'applications_transmission_mfr_code',
                        'applications_transmission_mfr',
                        'applications_wheel_base',
                        'applications_notes',
                        'applications_notes_record_number',
                        'applications_qualifier',
                        'applications_qualifier_values',
                        'applications_qualifier_text',
                        'applications_asset_name',
                        'applications_asset_type',
                        'applications_asset_representation',
        ];//end $enableKeys
        foreach($items as $item){
            $newItem = [];
            foreach($enableKeys as $enableKey){
                if(isset($item[$enableKey])){
                    $newKey = substr($enableKey,strlen('applications_'));
                    $newItem[$newKey] = $item[$enableKey];
                }
            }
			$row = Db::table('api_pdm_applications')
					->where([
					    ['brand',$newItem['brand']],
					    ['part_number',$newItem['part_number']],
					    ['app_id',$newItem['app_id']],
					])
					->first();
			if(!empty($row)){
				Db::table('api_pdm_applications')
					->updateOrInsert(
						[
						    'brand'=>$newItem['brand'],
						    'part_number'=>$newItem['part_number'],
						    'app_id'=>$newItem['app_id'],
						],
						$newItem
					);
			}else{
				Db::table('api_pdm_applications')->insertOrIgnore($newItem);
			}
            
        }
    }    
}