<?php

namespace App\Jobs\OpenWork\Contactway;

use Illuminate\Bus\Queueable;
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\OpenWork\Contactway\Qrcode as Model;
use App\Servers\Aliyun\Oss;
use App\Models\OpenWork\DownloadTask as DownloadTaskModel;

/**
 * SCRM 渠道活码异步导出
 * @author  唐远望
 * @version  1.0
 * @date   2025-09-28
 */
class QrcodeExportJobs 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;
    }

    public function handle()
    {
        try {
            // 商户ID
            $companyId                  = $this->message_data['company_id'];
            $file_id                    = $this->message_data['file_id'];
            $corpid                     = $this->message_data['corpid'];
            // 切换商户ID
            $result                     = (new DbService())->getConnectionNameByCompanyId($companyId);
            // 数据库链接失败
            if ( isset($result['error']) ) {
                Log::info('job_error', '渠道活码队列执行失败-切换数据库失败', ['data' => $this->message_data, 'error' => $result['error']]);
                return;
            }
            // 创建任务记录
            $this->Records              = Records::create([
                                            'job_id' => $companyId . '_CompanySyncTagGroupJobs',
                                            'name' => static::class,
                                            'payload' => json_encode($this->message_data),
                                            'status' => 'processing',
                                            'started_at' => now()
                                        ]);
            // 查询下载任务
            $downloadTask               = DownloadTaskModel::where(['file_id' => $file_id, 'corpid' => $corpid])->first();
            // 下载任务不存在
            if (!$downloadTask)         {
                // 删除任务记录
                $this->Records->delete();
                Log::info('job_error', '渠道活码队列执行失败-下载任务不存在', ['data' => $this->message_data]);
                return;
            }
            // 下载任务状态为2，则返回
            $oss_url                    = $this->download();
            // 上传失败
            if (!$oss_url) {
                $downloadTask->status = 2;
                $downloadTask->update_time = time();
                $downloadTask->save();
            }
            //删除任务记录
            if ($this->Records) {
                $this->Records->delete();
            }
        } catch (\Exception $e) {
            // 失败处理...
            if ($this->Records) {
                $this->Records->delete();
            }
            Log::info('job_error', '渠道活码队列执行失败', ['data' => $this->message_data, 'error' => $e->getMessage()]);
        }
    }

    /**
     * 执行下载打包任务
     * @author  唐远望
     * @version  1.0
     * @date   2025-09-28
     */
    public function download()
    {
        $Model                          = new Model();
        $ossClient                      = new Oss();
        $chunkSize                      = 100;
        // 文件ID
        $file_id                        = $this->message_data['file_id'];
        $companyId                      = $this->message_data['company_id'];
        $corpid                         = $this->message_data['corpid'];
        $checkedList                    = isset($this->message_data['request_data']['ids']) ? explode(',', $this->message_data['request_data']['ids']) : '';
        // 生成文件名
        $filename                       = '渠道活码_' . $file_id . '.zip';
        $fullPath                       = public_path('uploads/c/'.$companyId.'/zip');
        // 确保目录存在
        if ( !is_dir($fullPath) )       mkdir($fullPath, 0755, true);
        // 生成文件路径
        $fullPath                       = rtrim($fullPath,'/').'/'. $filename;
        // 查询数据
        $query                          = $Model->query()->where([['corpid', '=', $corpid]]);
        if ($checkedList)               $query = $query->whereIn('id', $checkedList);
        $query                          = $query->select(['id', 'remark', 'qr_code']);
        // 压缩实例
        $zip                            = new \ZipArchive;
        // 创建压缩文件
        $zip->open($fullPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
        //分块处理数据
        $query->chunk($chunkSize, function ($chunk) use ($zip,$companyId,$Model) {
            // 循环数据
            foreach ($chunk as $item)   {
                // 转换数据格式
                $item                   = $item->toArray();
                // 生成二维码图片
                $filePath               = $Model->writeQrcodeToFile($item['qr_code'],$companyId);
                // 添加文件到压缩包
                if( $filePath )         $zip->addFile($filePath,$item['remark'] . '_' . $item['id'] . '.png');
            }
            // 每处理完一个块，释放内存
            unset($chunk);
            gc_collect_cycles();
        });
        // 关闭压缩文件
        $zip->close();
        // 上传文件到OSS
        $ossPath                        = 'uploads/c/'.$companyId.'/scrm/contactway/'.$filename;
        // 上传文件
        $oss_url                        = $ossClient->putObject($ossPath, file_get_contents($fullPath));
        // OSS上传失败
        if ( !$oss_url )                Log::info('job_error', '渠道活码队列执行失败-OSS上传失败', ['data' => $this->message_data]);
        // 删除临时文件
        unlink($fullPath);
        //查询下载任务
        $downloadTask = DownloadTaskModel::where(['file_id' => $file_id, 'corpid' => $corpid])->first();
        if ($downloadTask) {
            $downloadTask->url          = $oss_url;
            $downloadTask->file_dir_name= $filename;
            $downloadTask->update_time  = time();
            $downloadTask->status       = 1;
            $downloadTask->save();
        }
        return                          $oss_url;
    }




    public function failed(\Throwable $exception)
    {
        Log::info('job_error', '渠道活码队列执行完全失败', ['data' => $this->message_data, 'error' => $exception]);
        if ($this->Records) {
            $this->Records->delete();
        }
    }


    
}
