<?php

namespace App\Console\Commands;

use App\Distributor\Repositories\SmmPost;
use App\Distributor\Repositories\SmmPostLog;
use App\Distributor\Repositories\SmmUserAccount;
use App\Libraries\CommonHelper;
use App\Services\SmmService;
use Carbon\Carbon;
use Dcat\Admin\Traits\HasUploadedFile;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Component\DomCrawler\Crawler;


/**
 * 定时任务:发送社媒帖子
 * php artisan timer:ssmPost
 */
class TimerSsmPost extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'timer:ssmPost';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '发送社媒帖子';


    use HasUploadedFile;

    public function handle()
    {
        try {
            //创建日志
            Log::info('开始生成发送帖子日志');
            $this->createLog();

            //刷新access_token
            Log::info('开始刷新access_token');
            $this->refreshAccessToken();

            //上传图片到oss
            Log::info('开始上传图片到oss');
            $ossUpload = $this->ossUpload();
            if (!$ossUpload) {
                Log::info('有正在上传的图片,请稍后再试,结束流程');
                echo '有正在上传的图片,请稍后再试';
                exit;
            }

            //开始发送社媒帖子
            Log::info('开始发送社媒帖子');
            $sendLog = SmmPostLog::getSendLog(5);
            $logIds = [];
            foreach ($sendLog as $log) {
                Log::info('开始发送社媒帖子,id:'. $log->id);
                echo '开始发送社媒帖子,id:'. $log->id. "\n";
                if ($log->media_name == 'Twitter' && SmmPostLog::twitterCanSend() == false) {
                    //15分钟内不重复发送
                    Log::info('twitter可发送时间未到,暂时无法发送,ID'.$log->post_id);
                    continue;
                }
                Log::info('开始发送社媒帖子,把状态改为发送中');
                //发送社媒帖子中
                $log->status = 1;//发送中
                $log->request_count = $log->request_count + 1;
                $log->updated_at = Carbon::now();
                $log->save();
                //发送社媒帖子中 end

                $logIds[] = $log->id;
                //获取帖子内容
                $post = SmmPost::getPostById($log->post_id);
                $message = $post->message;
                $imageVideoUrl = $post->image_video_url;
                $mediaName = $log->media_name;
                $postType = $post->post_type;
                $accountInfo = SmmUserAccount::getAccountById($log->account_id);
                $accessToken = $accountInfo->access_token;
                //发送帖子
                $configData = ['accountInfo' => $accountInfo->toArray(),'postData'=>$post->toArray()];
                $ssmService = new SmmService($mediaName,$configData);
                if ($postType == 0) {
                    //图片帖子
                    $imageVideoUrl = explode(',', $imageVideoUrl);
                    foreach ($imageVideoUrl as $key => $url) {
                        $imageVideoUrl[$key] = CommonHelper::ossUrl($url);
                    }
                    $response = $ssmService->postImage($message, $imageVideoUrl,$accessToken);
                    Log::info('图片帖子返回'.json_encode($response));
                } else {
                    $imageVideoUrl = CommonHelper::ossUrl($imageVideoUrl);
                    $response = $ssmService->postVideo($message, $imageVideoUrl,$accessToken);
                    Log::info('视频帖子返回'.json_encode($response));
                }
                $responseIds = isset($response['data']['responseIds'])? $response['data']['responseIds'] : [];
                //更新post_logs表
                if ($response['status'] == true) {
                    $log->status = 2;//发送成功
                    $log->response_ids = json_encode($responseIds);
                    $log->updated_at = Carbon::now();
                    $log->send_time = Carbon::now();
                    $log->save();
                } else {
                    $log->status = 3;//发送失败
                    $log->remark = $response['data'];
                    $log->updated_at = Carbon::now();
                    $log->send_time = Carbon::now();
                    $log->save();
                }
            }
            $logIds = json_encode($logIds);
            Log::info('发送社媒帖子完成'.$logIds);
            dd('发送社媒帖子完成'.$logIds);
        } catch (\Exception $e) {
            Log::info('发送社媒帖子失败:'.$e->getMessage());
            dd('发送社媒帖子失败:'.$e->getMessage());
        }
    }

    /*
     * access_token 过期重新获取
     * 1.Facebook 有效期60天,要手动重新获取
     * 2.Instagram 与 Facebook 一样
     * YouTube 有效期为 3600 秒,提前 10 分钟更新 access_token
     * Twitter 好像是过期
     */


    public function refreshAccessToken()
    {
        $accounts = SmmUserAccount::getAllYouTubeUserAccounts();
        foreach ($accounts as $account) {
            try {
                $expiresAt = Carbon::parse($account->expires_at);
                //少于15分钟就开始刷新access_token
                if ($expiresAt->diffInSeconds(Carbon::now()) <= 900) {
                    Log::info('开始刷新access_token:'. $account->name);
                    $mediaName = $account->getParent->name;
                    $configData = ['accountInfo' => $account->toArray()];

                    $ssmService = new SmmService($mediaName, $configData);
                    $result = $ssmService->refreshAccessToken($account->refresh_token);

                    if ($result['status'])  {
                        $account->access_token = $result['data']['access_token'];
                        $account->expires_at = $result['data']['expires_at'];
                        $account->refresh_token = $result['data']['refresh_token'];
                        $account->save();
                        Log::info('access_token 刷新成功:'. $account->name);
                    } else {
                        Log::info('access_token 刷新失败:'. $result['data']);
                    }
                }
            } catch (\Exception $e) {
                Log::info('access_token 刷新失败:'. $account->name.$e->getMessage());
            }
        }
    }

    /*
     * 生成发送帖子日志
     */
    public function createLog()
    {
        // 发送社媒帖子
        $waitPost = SmmPost::getWaitPost();
        foreach ($waitPost as $post) {
            //插入post_logs表
            $accountIds = explode(',', $post->account_ids);
            $accounts = SmmUserAccount::getAccountsByIds($accountIds);
            foreach ($accounts as $account) {
                $send_time = Carbon::now();
                // 如果是Twitter,15分钟内只能发一个帖
                if ($account->getParent->name == 'Twitter') {
                    $send_time = SmmPostLog::getTwitterSendTime();
                }
                //生成post_logs表数据
                $data = [
                    'post_id' => $post->id,
                    'account_id' => $account->id,
                    'account_name' => $account->name,
                    'status' => 0,
                    'remark' => '',
                    'created_at' => Carbon::now(),
                    'updated_at' => Carbon::now(),
                    'dist_id' => $account->dist_id,
                    'media_name' => $account->getParent->name,
                    'response_ids'=> '',
                    'send_time' => $send_time,
                ];
                SmmPostLog::createLog($data);
                Log::info('生成发送帖子日志:'. $post->id. ','. $account->name. ','. $send_time);
            }
            $post->status = 1;
            $post->save();
        }
    }


    public function ossUpload()
    {
        $count = SmmPost::getOssUploadingPostCount();
        if ($count > 0) {
            return false;
        }
        // 发送社媒帖子
        $ossUploadPost = SmmPost::getOssUploadPost();
        $disk = $this->disk('oss');
        foreach ($ossUploadPost as $post) {
            $post->oss_upload = 1;//上传中
            $post->save();
            //上传图片到oss
            $imageVideoUrl = explode(',', $post->image_video_url);
            foreach ($imageVideoUrl as $key => $url) {
                $localPath = toStoragePath($url);
                $filename = basename($url);
                $dir = dirname($url);
                $disk->putFileAs($dir, $localPath, $filename);
            }
            $post->oss_upload = 2; //上传完成
            $post->save();
        }
        return true;
    }

}