<?php

namespace App\Jobs\OpenWork\External;

use App\Servers\DB\DbService;
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\Wechat\OpenWork;
use App\Models\OpenWork\External\MarkTagLog;
use App\Models\OpenWork\External\FollowTag as FollowTagModel;
use Illuminate\Support\Facades\DB;
use App\Models\OpenWork\External\Tag as TagModel;
use App\Facades\Servers\Logs\Log;
use App\Models\OpenWork\job\Records;
use App\Models\Company\Corp\AuthCorp as AuthCorpmodel;
use App\Models\OpenWork\External\TagRelation as TagRelationModel;
use App\Servers\OpenWork\External\TagLogService;
use App\Models\OpenWork\External\CompanyUserTags as CompanyUserTagsModel;
use App\Models\OpenWork\External\User as UserModel;
use App\Models\OpenWork\External\Follow as FollowModel;
use App\Models\Manager\CustomExternal;
use App\Servers\OpenWork\External\ContactService;


/**
 * 批量打标签队列
 * @author    唐远望
 * @version   1.0
 * @date      2025-04-03
 * 
 */
class MarkTagJobs implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $mark_tag_log; //本地标签修改记录
    protected $mark_tag_log_weixin; //微信标签修改记录
    private $FollowTagModel;
    private $TagModel;
    private $Records;
    private $corpid;
    private $payload_content;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(array $mark_tag_log, array $mark_tag_log_weixin)
    {
        $this->mark_tag_log = $mark_tag_log;
        $this->mark_tag_log_weixin = $mark_tag_log_weixin;
        $this->corpid = 'xxx';
        $this->payload_content = '';
        if (!empty($mark_tag_log)) {
            $this->corpid = $mark_tag_log['corpid'];
            $this->payload_content = $mark_tag_log;
        }
        if (!empty($mark_tag_log_weixin)) {
            $this->corpid = $mark_tag_log_weixin['corpid'];
            $this->payload_content = $mark_tag_log_weixin;
        }


    }



    public function getCorpId()
    {
        return $this->corpid ?? null;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

        try {
            (new DbService())->getConnectionNameByCorpId($this->corpid);
            // 创建任务记录
            $this->Records = Records::create([
                'job_id' => $this->corpid . '_MarkTagJobs',
                'name' => static::class,
                'payload' => json_encode($this->payload_content),
                'status' => 'processing',
                'started_at' => now()
            ]);
            $mark_tag_log = $this->mark_tag_log;
            if (is_array($mark_tag_log) && count($mark_tag_log) > 0) {
                //查询用户是否存在
                $this->add_tag_log($mark_tag_log);
            } else {
                $mark_tag_log_weixin = $this->mark_tag_log_weixin;
                $MarkTagLogModel = new MarkTagLog();
                if (is_array($mark_tag_log_weixin) && count($mark_tag_log_weixin) > 0) {
                    //查询用户是否存在
                    $wx_result = $this->edit_tag($mark_tag_log_weixin);
                    if (!$wx_result && isset($mark_tag_log_weixin['id'])) {
                        $MarkTagLogModel->where('id', $mark_tag_log_weixin['id'])->update(['status' => 0, 'update_time' => time()]); //修改状态为失败
                    } else if (isset($mark_tag_log_weixin['id'])) {
                        $MarkTagLogModel->where('id', $mark_tag_log_weixin['id'])->update(['status' => 2, 'update_time' => time()]); //修改状态为成功
                    }
                }
                
            }
            //删除任务记录
            $this->Records->delete();
            // 成功处理...
        } catch (\Exception $e) {
            // 失败处理...
            if ($this->Records) {
                $this->Records->delete();
            }
            Log::info('job_error', 'MarkTagJobs任务队列处理失败', ['data' => [$this->mark_tag_log, $this->mark_tag_log_weixin], 'error' => $e->getMessage()]);
        }
    }


    /**
     * 给客户打标签
     * @param $data
     * @return bool
     */
    public function mark_tags($data_info)
    {
        $TagLogService = new TagLogService();
        $this->FollowTagModel = new FollowTagModel();
        $this->TagModel = new TagModel();
        $authCorpId                 = $data_info['corpid'];
        $data['userid']             = $data_info['userid'];
        $data['external_userid']    = $data_info['external_userid'];
        $data['add_tag']            = $data_info['add_tag'];
        $data['add_tag']            = $data['add_tag'] ? explode(',', $data['add_tag']) : [];
        $data['remove_tag']         = $data_info['remove_tag'];
        $data['remove_tag']            = $data['remove_tag'] ? explode(',', $data['remove_tag']) : [];
        $is_notice_saas = isset($data_info['is_notice_saas']) ? $data_info['is_notice_saas'] : 0;
        //删除标签条件
        $del_where = [
            'corpid' => $authCorpId,
            'follow_userid' => $data['userid'],
            'external_userid' => $data['external_userid'],
        ];
        //处理多个标签
        $add_data = [];
        if (count($data['add_tag']) > 0) {
            foreach ($data['add_tag'] as $key => $value) {
                $tag_name = $this->TagModel->where(['corpid' => $authCorpId, 'tag_id' => $value])->value('tag_name');
                if (!$tag_name) {
                   continue;
                }
                //查询是否存在
                $follow_tag_data = $this->FollowTagModel->where([
                    'corpid' => $authCorpId,
                    'follow_userid' => $data['userid'],
                    'external_userid' => $data['external_userid'],
                    'tag_id' => $value,
                ])->first();

                if ($follow_tag_data) {
                    continue;
                }
                $add_data[$key] = [
                    'corpid' => $authCorpId,
                    'follow_userid' => $data['userid'],
                    'external_userid' => $data['external_userid'],
                    'tag_id' => $value,
                    'tag_name' => $tag_name,
                    'type' => 1,
                    'insert_time' => time(),
                ];
            }
        }
        //事务处理

        DB::connection('company')->beginTransaction();


        try {
            $result = '';
            //删除标签
            if (count($data['remove_tag']) > 0) {
                $result = $this->FollowTagModel->query()->where($del_where)->whereIn('tag_id', $data['remove_tag'])->delete();

                if ($is_notice_saas) {
                    //同步标签到SASS平台
                    $del_tag_id_list = $data['remove_tag'];
                    $extid = $data['external_userid'];
                    $TagLogService->del_user_tag_sync_info($del_tag_id_list, $authCorpId, [$extid]);
                }
            }
            //添加标签
            if (count($add_data) > 0) {
                $result = $this->FollowTagModel->query()->insert($add_data);
                if ($is_notice_saas) {
                    //同步标签到SASS平台
                    $external_userid_array = array_column($add_data, 'external_userid');
                    $external_userids = implode(',', $external_userid_array);
                    $TagLogService->add_user_tag_sync_info($authCorpId, $external_userids);
                }
            }
            DB::connection('company')->commit();

            return $result;
            // 成功处理...
        } catch (\Exception $e) {
            DB::connection('company')->rollBack();

            if (stripos($e->getMessage(), 'UNIQUE_') === false) {
                Log::info('job_error', '批量给客户打标签失败', ['data' => $data_info, 'error' => $e->getMessage()]);
            }
            // 打印异常信息并终止执行
            return ['errcode' => 'error', 'errcode' => 1, 'errmsg' => $e->getMessage()];
        }
    }

    /**
     * 添加企业客户标签修改记录
     */
    public function add_tag_log($data)
    {
        // 添加修改记录
        $mark_tag_log = [
            'crowd_packid'   => $data['crowd_packid'],
            'corpid'             => $data['corpid'],
            'userid'           => $data['userid'],
            'external_userid'               => $data['external_userid'],
            'add_tag'         => $data['add_tag'],
            'remove_tag'         => $data['remove_tag'],
            'insert_time'     => time(),
        ];

        $mark_tag_log_id = (new MarkTagLog())->insertGetId($mark_tag_log);

        if (!$mark_tag_log_id)      return false;
        // 继续添加队列完成标签修改
        $mark_tag_log['id'] = $mark_tag_log_id;
        $mark_tag_log['execution_count'] = 1;
        $mark_tag_log['is_notice_saas'] = $data['is_notice_saas'];
        $this->dispatch([], $mark_tag_log); //异步添加
        // $this->dispatchSync([], $mark_tag_log);//同步添加
        return            true;
    }





    /**
     * 编辑企业客户标签     
     * @author  唐远望
     * @version 1.0
     * @date 2025-11-12
     */
    public function edit_tag($mark_tag_log)
    {
        $authCorpId = $mark_tag_log['corpid'];
        $userid = $mark_tag_log['userid'];
        $external_userid_list = $mark_tag_log['external_userid'];
        $add_tag = $mark_tag_log['add_tag'];
        $remove_tag = $mark_tag_log['remove_tag'];
        $execution_count = $mark_tag_log['execution_count'] ?? 1;
        $is_notice_saas = isset($mark_tag_log['is_notice_saas']) ? $mark_tag_log['is_notice_saas'] : 0;

        $TagModel = new TagModel();
        // 数据结果
        $data['userid']         = $userid;
        $data['external_userid']    = $external_userid_list;
        if ($add_tag) {
            $data['add_tag']            = $add_tag;
            $data['add_tag']            = explode(',', $data['add_tag']);
            //过滤已经被删除的标签
            $tags_array = $TagModel->query()->whereIn('tag_id', $data['add_tag'])->pluck('tag_id')->toarray();
            if (!empty($tags_array)) {
                $data['add_tag'] = $tags_array;
                $add_tag = implode(',', $tags_array);
            } else {
                unset($data['add_tag']);
            }
        }
        if ($remove_tag) {
            $data['remove_tag']         = $remove_tag;
            $data['remove_tag']            = explode(',', $data['remove_tag']);
            $tags_array = $TagModel->query()->whereIn('tag_id', $data['remove_tag'])->pluck('tag_id')->toarray();
            if (!empty($tags_array)) {
                $data['remove_tag'] = $tags_array;
                $remove_tag = implode(',', $tags_array);
            } else {
                unset($data['remove_tag']);
            }
        }
        $work                       = OpenWork::getWork($authCorpId);
        // 数据结果
        $result                     = $work->external_contact->markTags($data);
        if (!$result['errcode'] == 0) {
            if ($result['errcode'] == 45035) { //并发操作冲突
                if ($execution_count > 2) {
                    Log::info('job_error', '批量给客户打标签失败,重试了3次仍然失败', ['data' => $data, 'error' => $result]);
                    return false;
                }
                $mark_tag_log['execution_count'] = $execution_count + 1;
                $seconds = 10 * $mark_tag_log['execution_count']; //每次延长10秒
                $this->dispatch([], $mark_tag_log)->delay($seconds);
            } else {
                Log::info('job_error', '批量给客户打标签失败', ['data' => $data, 'error' => $result]);
                return false;
            }
        } else {
            // 处理数据
            $data_info['corpid'] = $authCorpId;
            $data_info['userid'] = $userid;
            $data_info['external_userid'] = $external_userid_list;
            $data_info['add_tag'] = $add_tag;
            $data_info['remove_tag'] = $remove_tag;
            $data_info['is_notice_saas'] = $is_notice_saas;
            $this->mark_tags($data_info);
        }
    }



    /**
     * 同步sass客户标签
     * @author  唐远望
     * @version 1.0
     * @date 2025-09-24
     */
    public function sync_sass_tag($corpid, $remove_tag)
    {
        if (!$remove_tag) {
            return true;
        }
        $remove_tag = explode(',', $remove_tag);
        $AuthCorpmodel = new AuthCorpmodel();
        $TagRelationModel = new TagRelationModel();
        $CompanyUserTagsModel = new CompanyUserTagsModel();
        $authcorp = $AuthCorpmodel->where([['corpid', '=', $corpid]])->first();
        if (!$authcorp) {
            Log::info('job_error', '未找到商户绑定企微信息', ['corpid' => $corpid]);
            return true;
        }
        foreach ($remove_tag as $value) {
            //查询标签映射关系
            $tag_relation_data = $TagRelationModel->query()->where(['company_id' => $authcorp->company_id, 'scrm_tag_id' => $value])->first();
            if ($tag_relation_data) {
                //如果存在用户绑定标签，则删除
                $user_tag_data = $CompanyUserTagsModel->query()->where(['company_id' => $authcorp->company_id, 'tag_id' => $tag_relation_data->sass_tag_id])->first();
                if ($user_tag_data) {
                    $CompanyUserTagsModel->query()->where(['company_id' => $authcorp->company_id, 'tag_id' => $tag_relation_data->sass_tag_id])->delete();
                }
            }
        }
        return true;
    }

    public function failed(\Throwable $exception)
    {
        Log::info('job_error', 'MarkTagJobs彻底失败', ['data' => [$this->mark_tag_log, $this->mark_tag_log_weixin], 'error' => $exception->getMessage()]);
        // 失败处理...
        if ($this->Records) {
            $this->Records->delete();
        }
    }
}
