<?php

namespace App\Jobs\Company\Corp;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\Facades\Servers\Logs\Log;
use App\Servers\DB\DbService;
use App\Models\OpenWork\job\Records;
use App\Models\Company\Corp\FollwTag as CorpFollwTagModel;
use App\Models\Company\Corp\TagRelation as TagRelationModel;
use App\Models\Company\Custom\Tag as CustomTagModel;
use App\Jobs\OpenWork\External\UserTagCacheJobs;

/**
 * 商户同步客户标签-打标签
 * @author  唐远望
 * @version  1.0
 * @date   2025-09-23
 */
class ExternalTagJobs implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    protected $message_data;
    protected $Records;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(array $message_data)
    {
        $this->message_data = $message_data;
    }

    /**
     * Execute the job.
     * 如果本地已同步的企微标签数量等于企微标签数量，则更新任务记录为成功
     * 标签上限  （https://developer.work.weixin.qq.com/document/path/92696#%E6%B7%BB%E5%8A%A0%E4%BC%81%E4%B8%9A%E5%AE%A2%E6%88%B7%E6%A0%87%E7%AD%BE）
     * 每个企业最多可配置10000个企业标签
     * 注：标签的节点可以是一个部门或一个人。
     * @return void
     */
    public function handle()
    {
        try {
            $companyId = $this->message_data['company_id'];
            (new DbService())->getConnectionNameByCompanyId($companyId);
            // 创建任务记录
            $this->Records = Records::create([
                'job_id' => $companyId . '_CompanySyncSpecifyTagJobs',
                'name' => static::class,
                'payload' => json_encode($this->message_data),
                'status' => 'processing',
                'started_at' => now()
            ]);
            $CorpFollwTagModel = new CorpFollwTagModel();
            $TagRelationModel = new TagRelationModel();
            $CustomTagModel = new CustomTagModel();
            $corpid = $this->message_data['corpid'];
            $local_tags_data = $this->message_data['local_tags_data'];
            $external_user_data = $this->message_data['external_user_data'];
            $external_userids = array_column($external_user_data, 'external_userid');
            $local_user_tag_data = $this->message_data['local_user_tag_data'];
            $user_id_relation = [];
            $user_ext_relation = [];
            if (!empty($external_user_data)) {
                foreach ($external_user_data as $key => $value) {
                    $custom_uid = $value['custom_uid'];
                    $external_userid = $value['external_userid'];
                    $user_id_relation[$custom_uid] = $external_userid;
                    if (array_key_exists($external_userid, $user_ext_relation)) {
                        $user_ext_relation[$external_userid] = $user_ext_relation[$external_userid] . ',' . $custom_uid;
                    } else {
                        $user_ext_relation[$external_userid] = $custom_uid;
                    }
                }
            }
            $insert_time = time();
            //查询用户对应的标签，并去重标签id
            $external_tag_datas = $CorpFollwTagModel->where('corpid', $corpid)->whereIn('external_userid', $external_userids)->select('external_userid', 'tag_id')->distinct()->get()
                ->groupBy('external_userid')->map(function ($items) {
                    return $items->pluck('tag_id')->implode(',');
                })
                ->toArray();

            foreach ($external_tag_datas as $key => $value) {
                $external_tag_datas[$key] = explode(',', $value);
            }
            //查询本地是否存在该标签的映射关系ID
            $local_tag_relation_ids = $TagRelationModel->where('company_id', $companyId)->get(['id', 'scrm_tag_id', 'sass_tag_id'])->toarray();
            $local_tag_relation = [];
            if (!empty($local_tag_relation_ids)) {
                foreach ($local_tag_relation_ids as $key =>  $local_tag_relation_data) {
                    $scrm_tag_id = $local_tag_relation_data['scrm_tag_id'];
                    $local_tag_relation[$scrm_tag_id] = $local_tag_relation_data['sass_tag_id'];
                }
            }
            $insert_tag_data = [];
            foreach ($external_tag_datas as $ext_id => $tag_ids) {
                //存在客服关系
                if (!array_key_exists($ext_id, $user_ext_relation)) {
                    continue;
                }
                $user_lists =  explode(',', $user_ext_relation[$ext_id]);
                foreach ($user_lists as $key => $user_id) {
                    foreach ($tag_ids as  $key =>  $tag_id) {
                        //存在映射关系
                        if (!empty($local_tag_relation) && array_key_exists($tag_id, $local_tag_relation)) {
                            $tag_id = $local_tag_relation[$tag_id];
                            if (!empty($local_user_tag_data) && array_key_exists($user_id, $local_user_tag_data) && in_array($tag_id, $local_user_tag_data[$user_id])) {
                                continue;
                            }
                            if(!in_array($tag_id,$local_tags_data)){
                                //存在映射关系，但是不存在标签数据，删除映射关系
                                $TagRelationModel->where('company_id', $companyId)->where('scrm_tag_id', $tag_id)->delete();
                                continue;
                            }
                            $insert_tag_data[] = [
                                'company_id' => $companyId,
                                'custom_uid' => $user_id,
                                'tag_id' => $tag_id,
                                'insert_time' => $insert_time
                            ];
                        }
                    }
                }
            }
            // $insert_tag_data = [];
            // $insert_time = time();
            // foreach ($external_user_data as $key => $value) {
            //     $custom_uid = $value['custom_uid'];
            //     $external_userid = $value['external_userid'];
            //     //查询用户对应的标签，并去重标签id
            //     $external_tag_data = $CorpFollwTagModel->where('corpid', $corpid)->where('external_userid', $external_userid)->distinct('tag_id')->pluck('tag_id')->toarray();
            //     //查询本地是否存在该标签的映射关系ID
            //     $local_tag_relation_id = $TagRelationModel->where('company_id', $companyId)->whereIn('scrm_tag_id', $external_tag_data)->pluck('sass_tag_id')->toarray();
            //     //查询本地用户已经存在的用户标签
            //     $local_user_tag_data = $CustomTagModel->where('company_id', $companyId)->where('custom_uid', $custom_uid)->whereIn('tag_id', $local_tag_relation_id)->pluck('tag_id')->toarray();
            //     //比较本地用户标签和企微标签的差异，如果有差异，则更新本地用户标签
            //     $diff_tag_data = array_diff($local_tag_relation_id, $local_user_tag_data);
            //     if (!empty($diff_tag_data)) {
            //         foreach ($diff_tag_data as $diff_tag_id) {
            //             $insert_tag_data[] = [
            //                 'company_id' => $companyId,
            //                 'custom_uid' => $custom_uid,
            //                 'tag_id' => $diff_tag_id,
            //                 'insert_time' => $insert_time
            //             ];
            //         }
            //     }
            // }
            if (!empty($insert_tag_data)) {
                $CustomTagModel->insert($insert_tag_data);
                //更新用户标签缓存
                foreach ($insert_tag_data as $key => $value) {
                    $custom_uid = $value['custom_uid'];
                    $message_data = [
                        'corpid' => $corpid,
                        'custom_uid' => $custom_uid,
                        'external_userid' => $user_id_relation[$custom_uid],
                        'company_id' => $companyId,
                    ];
                    UserTagCacheJobs::dispatch($message_data);
                    // UserTagCacheJobs::dispatchSync($message_data);
                }
            }
            //删除任务记录
            if ($this->Records) {
                $this->Records->delete();
            }
        } catch (\Exception $e) {
            // 失败处理...
            if ($this->Records) {
                $this->Records->delete();
            }
            // 如果错误信息里面包含字符UNIQUE_（数据唯一）则不写日志
            if (stripos($e->getMessage(), 'UNIQUE_') === false) {
                Log::info('job_error', '商户同步客户标签队列-打标签同步失败', ['data' => $this->message_data, 'error' => $e->getMessage()]);
            }
        }
    }

    public function failed(\Throwable $exception)
    {
        Log::info('job_error', '商户同步客户标签队列-打标签执行失败', ['data' => $this->message_data, 'error' => $exception->getMessage()]);

        // 只有在Records存在时才删除
        if ($this->Records) {
            $this->Records->delete();
        }
    }
}
