<?php

namespace Controller;

use Lib\Mail\Mail;
use Lib\Mail\MailFun;
use Lib\UploadFile;
use Lib\Verify;
use Model\bodySql;
use Model\emailSql;
use Model\folderSql;
use Model\listsSql;
use Model\sendJobsSql;
use Service\SyncMail;


/**
 * @author:dc
 * @time 2023/2/13 11:28
 * Class Home
 * @package Controller
 */
class Home extends Base {


    /**
     * 邮件列表
     * @author:dc
     * @time 2023/2/17 14:12
     */
    public function lists(){

        // 分页 页数
        $page   =   app()->request('page',1,'intval');
        $page   =   $page ? $page : 1;

        $limit   =   app()->request('limit',20,'intval');
        $limit   =   $limit ? $limit : 1;

        // 指定id
        $ids = app()->request('mail_id');
        $ids = is_array($ids) ? $ids : [$ids];
        foreach ($ids as $i=>$d){
            if(!is_numeric($d)){
                unset($ids[$i]);
            }
        }

        // 附件
        $attachment =   app()->request('attachment',0,'bool_Val');
        // 已读/未读
        $seen =   app()->request('seen',-1,'intval');
        // 软删
        $deleted =   app()->request('deleted',0,'intval');


        $where = ['email_id'=>$this->getEmails('id')];


        $folder_id = ['-'];
        if (app()->requestArr('folder_id')){
            $folder_id = app()->requestArr('folder_id');
        }else{
            // 目录
            $folder = app()->request('folder','收件箱','folderAlias');
            if($folder !== true || $folder!=='true'){
                $folderList = db()->all(folderSql::all($where['email_id']));

                // 文件夹id
                if($folderList){
                    foreach ($folderList as $item){
                        if(
                            // 数组文件夹
                            (is_array($folder) && in_array($item['folder'],$folder))
                            || $item['folder'] == $folder
                        ){
                            $folder_id[] = $item['id'];
                        }
                    }
                }
            }

        }

        if(!$folder_id){
            app()->e('folder_not_fount');
        }
        $folder_id = array_filter($folder_id,'is_int');

        //目录
        if($folder_id) $where['folder_id'] = array_values($folder_id);
        if($ids) $where['id'] = $ids;

        if(paramHas('attachment')){
            $where['is_file'] = $attachment ? 1 : 0; //附件
        }


        // 软删
        $where['deleted'] = $deleted;
        // 已读/未读
        if(paramHas('seen')){
            if(in_array($seen,[0,1])){
                $where['seen'] = $seen;
            }
        }

        $where['_'] = [];
        // 搜索关键字
        $keyword = app()->request('keyword','',['htmlspecialchars','addslashes']);
        if($keyword){
            $where['_'][] = '`subject` like "%'.$keyword.'%"';
        }

        // 那个发的
        $address = app()->request('address');
        if($address){
            if(is_array($address)){
                // 发贱人
                if(Verify::sEmail($address['from']??'')){
                    $where['from'] = $address['from'];
                }
                // 收件人
                if(Verify::sEmail($address['to']??'')){
                    $where['_'][] = '`to_name` like "%'.$address.'%"';
                }

            }else if(Verify::sEmail($address)){
                // 收件人/发件人
                $where['_'][] = '(`from` = "'.$address.'" or `to_name` like "%'.$address.'%")';
            }
        }
        // from 搜索收件人
        if(app()->requestHas('from')){
            // 如果是发件箱
            if($folder == '发件箱'){
                $tos = app()->request('from');
                if(!$tos){
                    // 不让查询数据
                    $where['id'] = 0;
                }else {
                    $tos = array_map(function ($v){
                        return "find_in_set('".addcslashes($v,"'")."',`to`)";
                    },is_array($tos) ? $tos : [$tos]);

                    $where['_'][] = '('.implode(' or ',$tos).')';
                }
            }else{
                $where['from'] = app()->request('from');
                if(!$where['from']){
                    // 不让查询数据
                    $where['id'] = 0;
                }
            }


        }


        // 回复
        if (paramHas('answered')){
            $where['answered'] = app()->request('answered',0,'bool_Val')?1:0;
        }

        // 这个主要是来筛选 是否是自己发送的
        $fromto = app()->request('formorto');
        if($fromto=='from'){
            $where['from'] = $this->getEmails('email');
        }elseif ($fromto=='to'){
            $where['from.notin'] = $this->getEmails('email');
        }

        /**
         * 不查询哪些发件人的邮件
         */
        $form_not_in = app()->request('from_not_in');
        if($form_not_in){
            $form_not_in = is_array($form_not_in) ? $form_not_in : [$form_not_in];
            $form_not_in = array_filter($form_not_in,function ($v){
                if(is_string($v) && Verify::sEmail($v)){
                    return true;
                }
                return false;
            });
            if($form_not_in){
                if(isset($where['from.notin'])){
                    $where['from.notin'] = array_merge($where['from.notin'],$form_not_in);
                }else{
                    $where['from.notin'] = $form_not_in;
                }

            }
        }
        if(!empty($where['from.notin'])){
            $where['from.notin'] = array_unique($where['from.notin']);
        }



        $lists = db()->all(
            listsSql::lists(
                dbWhere($where),
                $page,
                $limit
            )
        );
        $lists = $lists ? $lists : [];

        // map
        $lists = array_map(function ($v){
            $v['uuid'] = get_email_uuid($v['subject'],$v['udate'],$v['from'],$v['to'],$v['size']);
            if(!empty($v['description'])){
                $v['description'] = @html_entity_decode($v['description'], ENT_COMPAT, 'UTF-8');
            }
            $v['to_name'] = @json_decode($v['to_name'],true);
            $v['to_name'] = $v['to_name']?:[];
            if($v['to_name']){
                if(!empty($v['to_name'][0]['email'])){
                    $v['to'] = $v['to_name'][0]['email'];
                }
                $v['to_name'] = MailFun::mb_coding($v['to_name'][0]['name']??'');
            }
            if(is_array($v['to_name'])){
                $v['to_name'] = '';
            }
            // 邮件箱
            $v['folder_name'] = db()->cache(86400)->value(folderSql::first($v['folder_id'],'folder'));
            return $v;
        },$lists);

        // 总数
        $total  = db()->count(
            listsSql::listCount(dbWhere($where))
        );

        app()->_json(listsPage($lists,$total,$page,$limit));

    }

    /**
     * 统计
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/10/14 16:20
     */
    public function count()
    {

        $where = [];


        $start_time = app()->request('start_time',0,'intval');
        $end_time = app()->request('end_time',0,'intval');
//        if($start_time || $end_time){
//            $where['email_id'] = $this->getEmails('id');
//        }
        $where['_'] = [];
        if($start_time){
            $where['_'][] = '`udate` >= '.$start_time;
        }
        if($end_time){
            $where['_'][] = '`udate` <= '.$end_time;
        }

        $where['_'] && $where['_'] = implode(' and ',$where['_']);

        $where['folder_id'] = [];

        // 目录
        $folderList = db()->all(folderSql::all($this->getEmails('id')));

        // 文件夹id
        foreach ($folderList as $item) {
            if ($item['folder'] == '收件箱') {
                $where['folder_id'][] = $item['id'];
            }
        }


        // 软删
        $where['deleted'] = 0;

        // 总数
        $inbox  = db()->cache(3600)->count(listsSql::listCount(dbWhere($where)));

        if(app()->request('show')=='inbox'){
            app()->_json(['inbox'=>$inbox]);
        }

        // 未读
        $where['seen'] = 0;
        $unseen  = db()->cache(3600)->count(listsSql::listCount(dbWhere($where)));


        $where['folder_id'] = [];
        foreach ($folderList as $item) {
            if ($item['folder'] == '发件箱') {
                $where['folder_id'][] = $item['id'];
            }
        }
        unset($where['seen']);
        //发件箱
        $send  = db()->cache(3600)->count(listsSql::listCount(dbWhere($where)));

        app()->_json(['inbox'=>$inbox,'unseen'=>$unseen,'send'=>$send]);
    }

    /**
     * 检测邮箱状态
     * @author:dc
     * @time 2023/3/28 16:19
     */
    public function check(){



        $lists = db()->all(emailSql::getValues(['email'=>web_request_emails()],'`id`,`pwd_error`,`email`,`password`,`imap`'));
        return array_column($lists,'pwd_error','email');

        foreach ($lists as $k=>$list){
            if(!$list['pwd_error']){
                $mail = new \Lib\Mail\Mail($list['email'],base64_decode($list['password']),$list['imap']);

                // 2次登录请求
                if($mail->login()!==1){
                    if($mail->login()!==1){
                        $lists[$k]['pwd_error'] = 1;
                    }
                }
                $mail = null;
            }

        }

        return array_column($lists,'pwd_error','email');

    }


    /**
     * 发送邮件
     * @author:dc
     * @time 2023/2/18 17:32
     */
    public function send_mail(){

        $email = $this->getEmail();

        $yzemail = function(&$value,$field){
            if($value){
                if(!is_array($value)){
                    if(@json_decode($value,true)){
                        $value =    json_decode($value,true);
                    }else{
                        $value = [['email'=>$value,'name'=>'']];
                    }
                }
                foreach ($value as $item){
                    if(!Verify::sEmail($item['email'])){
                        app()->e([$field.'_verify_error',$item['email']]);
                    }
                }
            }
        };

        $formData = Verify::checks([
            'nickname|'.__('nickname')  =>  ['max'=>50],
            'subject|'.__('subject')  =>  ['required','max'=>500],
            'body|'.__('body_email')  =>  ['required'],
            'tos|'.__('to_email')  =>  ['required',$yzemail],
            'cc|'.__('to_cc')  =>  [$yzemail],
            'bcc|'.__('to_bcc')  =>  [$yzemail],
            'priority|'.__('priority_email')  =>  ['in'=>[1,3,5]],
//            'attachment|'.__('files_email')  =>  [
//                'file'=>[
//                    'ext'   =>  [],
//                    'size'  =>  1024*1024*50,
//                    'mine'  =>  []
//                ]
//            ],
            'receipt|'.__('receipt_email')  =>  []
        ],[

        ]);


        $sendData = [];
        $sendData['email']   =   $email['email'];
        $sendData['nickname']   =   $formData['nickname']??'';
        $sendData['tos']   =   $formData['tos'];
        if(count($sendData['tos'])>100){
            app()->e(['tos_number_error',100]);
        }
//        抄送
        $sendData['cc'] = [];
        if(($formData['isCc']??0) && !empty($formData['cc'])){
            $sendData['cc'] =   $formData['cc'];
        }
        if(count($sendData['cc'])>10){
            app()->e(['cc_number_error',10]);
        }
        // 密送
        $sendData['bcc'] = [];
        if(($formData['isBcc']??0) && !empty($formData['bcc'])){
            $sendData['bcc'] =   $formData['bcc'];
        }

        // 添加自定义头信息 预热邮件
        if(!empty($formData['aicc-hot'])){
            $sendData['mail-header'] = [
                'Aicc-Hot-Mail' =>  'hot' // 预热邮件
            ];
        }

        if(count($sendData['bcc'])>10){
            app()->e(['bcc_number_error',10]);
        }
        $sendData['reply_to'] = [];//回复到那个邮件
        //Attachments 附件 上传的
        $sendData['attachment'] = [];
        // 这个是直接上传文件
        $attachment = app()->file('attachment');
        if($attachment){
            foreach ($attachment as $file){
                if($file->move()){
                    $sendData['attachment'][] = [
                        'name'  =>  $file->name,
                        'filename'  =>  $file->name,
                        'signName'  =>  $file->saveName,
                        'path'  =>  $file->savePath.$file->saveName
                    ];
                }else{
                    app()->e(['attachment_upload_error',$file->name]);
                }
            }
        }
        // 这个是通过了上传接口上传的文件
        $attachment = app()->request('attachmentapi');
        if($attachment){
            foreach ($attachment as $file){
                $file = json_decode($file,true);
                if(empty($file['data']['saveName'])|| !is_file(PUBLIC_PATH.$file['data']['saveName'])){
                    app()->e('附件('.$file['data']['name'].")异常");
                }
                $sendData['attachment'][] = [
                    'name'  =>  $file['data']['name'],
                    'filename'  =>  $file['data']['name'],
                    'signName'  =>  $file['data']['saveName'],
                    'path'  =>  PUBLIC_PATH.$file['data']['saveName']
                ];
            }
        }

        // 远程路径,云文件
        $attachmentUrl = app()->request('attachmentUrl');
        if(is_array($attachmentUrl)){
            foreach ($attachmentUrl as $file){
                $file = is_array($file) ? $file : json_decode($file,true);
                if(!empty($file['url']) && !empty($file['name'])){
                    $file = new UploadFile($file['name'],$file['url']);
                    if($file->move()){
                        $sendData['attachment'][] = [
                            'name'  =>  $file->name,
                            'filename'  =>  $file->name,
                            'signName'  =>  $file->saveName,
                            'path'  =>  $file->savePath.$file->saveName
                        ];
                    }else{
                        app()->e(['attachment_upload_error',$file->name]);
                    }
                }

            }
        }
        $sendData['receipt'] = empty($formData['receipt']) ? '' : 1;// 回执,阅读后收回执的邮箱
        $sendData['priority'] = $formData['priority']??3;// 是否紧急邮件
        $sendData['subject'] = $formData['subject'];// //Content 主题,标题
        // 删除script标记
        $sendData['body'] = strip_tags_content($formData['body'],'<script>',true);
        // 不重要的信息
        $sendData['jobName'] = $formData['jobName']??'';//任务标题
        $sendData['massSuit'] = $formData['massSuit']??0;// 是否是群发单显

        // 定时发送时间
        $timer = app()->request('timerValue',0);
        if(is_numeric($timer) && $timer){
            $timer = time()+$timer;
        }else if (is_string($timer)){
            $timer = strtotime($timer);
        }else{
            $timer = 0;
        }
        // 是否存草稿
        if(app()->request('saveType')=='draft'){
            // 保存
            $draftid =  listsSql::saveDraft($sendData,$email,app()->request('draft_id',0,'intval'));
            // 保存失败
            if($draftid){
                app()->_json(['draft_id'=>$draftid]);
            }
            app()->e('save_draft_error');

        }
        // 定时发送 或者是单条发送
        else if((app()->request('timer') &&  $timer > time()) || $sendData['massSuit']){

            if($sendData['massSuit']){
                // 每次发送间隔的时间
                $sendData['masssuit_interval_send']  = app()->request('masssuit_interval_send');
                $sendData['masssuit_interval_send']['start'] = intval($sendData['masssuit_interval_send']['start']??0);
                $sendData['masssuit_interval_send']['end'] = intval($sendData['masssuit_interval_send']['end']??1);
            }


            // 插入任务
            $job_id = db()->insert(sendJobsSql::$table,[
                'email_id'  =>  $email['id'],
                'maildata'  =>  $sendData,
                'title'  =>  $sendData['jobName'] ? : $sendData['subject'],
                'total'  =>  count($sendData['tos']),
                'send_time' =>  $timer?:time()
            ]);
            if($job_id){
                // 返回任务id
                app()->_json(['job_id'=>$job_id]);
            }

            app()->e('send_timer_job_error');
        }
        else{
            // 立即发送
            $result = MailFun::sendEmail($sendData,$email);
            if($result[0]){
                app()->_json(['messageId'   => $result[1]]);
            }
            // 错误
            app()->e($result[1]);
        }

    }


    /**
     * 收到前端的同步请求操作
     * @author:dc
     * @time 2023/3/10 10:38
     */
    public function sync(){

        $emails = web_request_emails();

        if(empty($emails)){
            app()->e('sync_request_param_error');
        }else{
            // 查询id
            if(count($emails)===1){
                $emails = $emails[0];
            }
            $datas = db()->cache(3600)->all(emailSql::getValues(['email'=>$emails],'`id`,`email`,`pwd_error`'));
            foreach ($datas as $k=>$v){
                if(!$v['pwd_error']){
                    if(app()->requestHas('blacklist')){
                        $blacklist = app()->request('blacklist');
                        if(is_array($blacklist)){
                            $blacklist = [
                                'emails' =>   $blacklist['emails']??[],
                                'domain' =>   $blacklist['domain']??[],
                            ];
                            // 黑名单,7天过期时间
                            redis()->set('blacklist:'.$v['id'],$blacklist,86400*7);
                        }
                        // 删除
                        if(!$blacklist||(empty($blacklist['emails'])&&empty($blacklist['domain']))){
                            redis()->delete('blacklist:'.$v['id']);
                        }

                    }
                    $source = app()->request('source');
                    redis()->rPush('sync_email_lists'.($source==1?'_my':''), $v['id']);
                }
                $datas[$k]['have_new'] = redis()->getDel('have_new_mail_'.$v['id']);

                // 计算
//                $folders = db()->all(folderSql::all($v['id'],'`id`'));
//                foreach ($folders as $folder){
//                    $w = [
//                        'email_id'  =>  $v['id'],
//                        'folder_id'  =>  $folder['id'],
//                    ];
//                    db()->update(folderSql::$table,[
//                        'exsts' =>  db()->count(listsSql::listCount(dbWhere($w))),
//                        'unseen' =>  db()->count(listsSql::listCount(dbWhere(array_merge($w,['seen'=>0])))),
//                    ],'`id` = '.$folder['id'],false);
//                }

            }
            // 返回成功的参数值
            app()->_json($datas);
        }

    }


    /**
     * 标记为已读
     * @throws \Lib\Err
     * @author:dc
     * @time 2023/3/17 16:15
     */
    public function seen_2_unseen(){
        $this->setFlags('seen');
    }

    /**
     * 是否已回复
     * @throws \Lib\Err
     * @author:dc
     * @time 2023/4/10 16:30
     */
    public function answered_2_unanswered(){
        $this->setFlags('answered');
    }

    /**
     * 星标
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/6/21 16:35
     */
    public function star_2_unstar(){
        $this->setFlags('flagged');
    }





    /**
     * 邮件移动
     * @author:dc
     * @time 2023/3/21 11:41
     */
    public function move(){
        $this->moveCopy(function (Mail $mailInstance,$uid,$origin_folder,$to_origin_folder){
//            try {
//                return $mailInstance->move($uid,$origin_folder,$to_origin_folder);
//            }catch (\Throwable $e){
//                if(app()->request('move_err_copy',1)){
            // 复制成功
            try {
                if($mailInstance->copy($uid,$origin_folder,$to_origin_folder)){
                    return $mailInstance->deleted($uid,$origin_folder);
                }
            }catch (\Throwable $e){
                logs('移动失败:'.$e->getMessage());
                return false;
            }

//                }
//            }
            return false;

        });
    }


    private function moveCopy(\Closure $call){
        $emails = $this->getEmails();

        $mail_ids = app()->requestArr('mail_ids');
        if(!($mail_ids && is_array($mail_ids))){
            app()->e('param_request_error');
        }
        foreach ($mail_ids as $k=>$id){
            if(!is_numeric($id)){
                unset($mail_ids[$k]);
            }
        }
        // 移动到的文件夹
        $to_folder = folderAlias(app()->request('folder'));
        if(empty($to_folder)){
            app()->e('folder_move_error');
        }
        if($to_folder == '草稿箱'){
            app()->e('folder_move_to_draft_error');
        }
        if($to_folder == '发件箱'){
            app()->e('folder_move_to_send_error');
        }

        $data  = db()->all(listsSql::all(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]),'`id`,`uid`,`email_id`,`folder_id`'));
        if($data){
            // 查询邮箱
            $emails = array_column($emails,null,'id');
            $uids = [];
            foreach ($data as $datum){
                // 只有草稿箱才没有uid
                if($datum['uid']<0){
                    // 删除
                    if ($to_folder == '回收站'){
                        // 删除数据,真实删除
                        db()->delete(listsSql::$table,[
                            'id'    =>  $datum['id']
                        ]);
                        continue;
                    }
                }

                if(empty($uids[$datum['email_id']][$datum['folder_id']])){
                    $uids[$datum['email_id']][$datum['folder_id']] = [];
                }
                $uids[$datum['email_id']][$datum['folder_id']][] = [
                    'uid'   =>   $datum['uid'],
                    'id'   =>   $datum['id'],
                ];
            }

            foreach ($uids as $eid=>$arr){
                // 查询需要移动的文件夹
                $to_origin_folder = db()->first(folderSql::first(['email_id'=>$eid,'folder'=>$to_folder]));
                if($to_origin_folder){
                    foreach ($arr as $fid=>$uid){
                        // 查询目录
                        $folder = db()->first(folderSql::first($fid));
                        if($folder){
                            // 开始远程
                            $mailInstance = new Mail($emails[$eid]['email'],base64_decode($emails[$eid]['password']),$emails[$eid]['imap']);

                            if($mailInstance->login()==1){
                                $localUids = array_column($uid,'uid');
                                // 检查 远程是否有邮件
                                $mailInstance->client->selectFolder($folder['origin_folder']);
                                $originUids = $mailInstance->client->fetch($localUids,'UID',true);

                                if($originUids){
                                    // 进行移动 远程有的邮件
                                    $ret = $call($mailInstance,array_column($originUids,'UID'),$folder['origin_folder'],$to_origin_folder['origin_folder']);
                                }else{
                                    $ret = true;
                                }

                                // TODO:: 这个过程无法保证原子性。没办法
                                // 先复制
                                if($ret){
                                    $uret = db()->update(listsSql::$table,['deleted'=>1],dbWhere(['id'=>array_column($uid,'id')]));
                                }


                            }
                            $mailInstance = null;

                        }
                        $folder = null;
                    }
                }


            }

        }


        app()->_json([
            'mail_id'    =>  $mail_ids
        ]);
    }


    /**
     * 复制邮件
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/3/9 13:50
     */
    public function copy(){
        $this->moveCopy(function (Mail $mailInstance,$uid,$origin_folder,$to_origin_folder){

            return $mailInstance->copy($uid,$origin_folder,$to_origin_folder);

        });
    }


    /**
     * 执行清空邮件操作
     * @throws \Lib\Err
     * @author:dc
     * @time 2024/3/14 14:18
     */
    public function expunge(){
        $email = $this->getEmail();
        $mailInstance = new Mail($email['email'],base64_decode($email['password']),$email['imap']);

        if($mailInstance->login()==1 && $mailInstance->expunge()){
            app()->_json([]);
        }

        app()->e('执行失败');
    }




    /**
     * 远程标签
     * @param $d
     * @throws \Lib\Err
     * @author:dc
     * @time 2023/3/21 14:28
     */
    private function setFlags($d){
        $emails = $this->getEmails();

        $mail_ids = app()->request('mail_ids');

        // 全部标记
        if(!$mail_ids){
            $folder = app()->request('folder','收件箱','folderAlias');
            // 查询 当前的 文件夹 如果有选中文件夹 就 查询出 选中文件夹的id
            $fids = db()->all(folderSql::all(array_column($emails,'id'),'`id`,`folder`'));
            foreach ($fids as $fk=>$fid){
                if($fid['folder'] != $folder){
                    unset($fids[$fk]);
                }
            }
            if($fids){
                // 查询要标记的 邮件id
                $sql = listsSql::all(dbWhere(['folder_id'=>array_column($fids,'id'),'seen'=>0]),'`id`');
                $mail_ids = db()->all($sql);
                $mail_ids2 = db()->all(str_replace('from `lists` where','from `lists_hot` where',$sql));
                $mail_ids = array_merge($mail_ids,$mail_ids2);
                $mail_ids = array_column($mail_ids,'id');
            }

        }

        if($mail_ids){
            $mail_ids = is_array($mail_ids) ? $mail_ids : explode(',',$mail_ids);
        }

        if(!($mail_ids && is_array($mail_ids))){
            app()->e('param_request_error');
        }
        foreach ($mail_ids as $k=>$id){
            if(!is_numeric($id)){
                unset($mail_ids[$k]);
            }
        }
        // 已读或未读
        $fv = (int) app()->request($d);
        $fv = $fv ? 1 : 0;

        $sql = listsSql::all(dbWhere(['id'=>$mail_ids,'email_id'=>array_column($emails,'id')]),'`id`,`uid`,`email_id`,`folder_id`');
        $data  = db()->all($sql);
        $data2  = db()->all(str_replace('from `lists` where','from `lists_hot` where',$sql));
        $data = array_merge($data,$data2);
        if($data){
            // 查询邮箱
            $emails = array_column($emails,null,'id');
            $uids = [];
            foreach ($data as $datum){
                if(empty($uids[$datum['email_id']])){
                    $uids[$datum['email_id']][$datum['folder_id']] = [];
                }
                $uids[$datum['email_id']][$datum['folder_id']][] = [
                    'uid'   =>   $datum['uid'],
                    'id'   =>   $datum['id'],
                ];
            }

            foreach ($uids as $eid=>$arr){
                foreach ($arr as $fid=>$uid){
                    // 查询目录
                    $folder = db()->first(folderSql::first($fid));
                    if($folder){
                        // 开始远程
                        $mailInstance = new Mail($emails[$eid]['email'],base64_decode($emails[$eid]['password']),$emails[$eid]['imap']);

                        if($mailInstance->login()==1){
                            switch ($d){
                                // 已读 未读
                                case 'seen':{
                                    $mailInstance->seen(array_column($uid,'uid'),$folder['origin_folder'],$fv);
                                    break;
                                }
                                // 未回复/已回复
                                case 'answered':{
                                    $mailInstance->answered(array_column($uid,'uid'),$folder['origin_folder'],$fv);
                                    break;
                                }
                                // 星标
                                case 'flagged':{
                                    $mailInstance->flagged(array_column($uid,'uid'),$folder['origin_folder'],$fv);
                                    break;
                                }
                                // 回收站,已删 未删,软删
//                                case 'deleted':{
//                                    $mailInstance->recycle(array_column($uid,'uid'),$folder['origin_folder'],$fv);
//                                    break;
//                                }
                            }

                            $mailInstance = null;
                            // 更新数据
                            db()->update(listsSql::$table,[
                                $d  =>  $fv
                            ],dbWhere([
                                'id'    =>  array_column($uid,'id')
                            ]));
                            db()->update('lists_hot',[
                                $d  =>  $fv
                            ],dbWhere([
                                'id'    =>  array_column($uid,'id')
                            ]));
                        }

                    }
                    $folder = null;
                }
            }

        }


        app()->_json([
            'mail_id'    =>  $mail_ids
        ]);

    }


    /**
     * @author:dc
     * @time 2023/4/1 9:24
     */
    public function info(){
        $reload = app()->request('reload',0,'intval');
        $sync_num = 0;
        HOME_INFO_BODY:
        $id =   app()->request('id',0,'intval');

        $udate = app()->request('udate',0,'intval');
        $subject = app()->request('subject');
        if($udate&&$subject){
            $data    =   db()->first(listsSql::first(dbWhere(['id'=>$id,'udate'=>$udate])));
//            if($data && trim($data['subject']) != trim($subject)){
//                $data = [];
//            }
            if($data){
                $email = db()->first(emailSql::first($data['email_id']));
            }
        }else{
            // 没有,说明没有同步过来
            $email = $this->getEmail('*',false);
            $data    =   db()->first(listsSql::first(dbWhere(['id'=>$id,'email_id'=>$email['id']])));
            if(!$data){
                $data    =   db()->first(listsSql::firstHot(dbWhere(['id'=>$id,'email_id'=>$email['id']])));
            }
        }

        if($data){
            $data['uuid'] = get_email_uuid($data['subject'],$data['udate'],$data['from'],$data['to'],$data['size']);

            $data['description'] = @html_entity_decode($data['description']??'', ENT_COMPAT, 'UTF-8');

            $data['to_name'] = $data['to_name'] ? json_decode($data['to_name'],true) : [];
            if(!$data['to_name']){
                $data['to_name'] = [["email"=>$email['email'],'name'=>'']];
            }
            $data['cc'] = $data['cc'] ? json_decode($data['cc'],true) : [];
            $data['bcc'] = $data['bcc'] ? json_decode($data['bcc'],true) : [];

            $data['to_name'] = array_map(function ($t){
                if(!empty($t['name'])){
                    $t['name'] = MailFun::mb_coding($t['name']);
                }
                return $t;
            },$data['to_name']);

            // 是否再次 重新获取
            $data['allowreply'] = db()->value(folderSql::first(['id'=>$data['folder_id']],'folder'))!='发件箱'?1:0;

            $body   =   db()->first(bodySql::first($id));
            if($body && !$reload){
                $data['body'] = json_decode($body['text_html'],true);
                $htmlbody = '';
                foreach ($data['body'] as $bd){
//                    if(!empty($bd['charset'])){
//                        $charset = $bd['charset'];
//                    }
                    if(($bd['type']??'') == 'text/html'){
                        $htmlbody = base64_decode($bd['body']);
                    }
                }
                foreach ($data['body'] as $bdk=>$bd){

                    if(count($bd)==1){
                        if(isset($bd['body'])){
                            $data['body'][$bdk]['type'] = 'text/html';
                        }
                    }

                    if(!empty($bd['path'])){

                        $data['body'][$bdk]['name'] = MailFun::isBase64($bd['name']) ? @base64_decode($bd['name']) : $bd['name'];
                        $data['body'][$bdk]['filename'] = MailFun::isBase64($bd['filename']) ? @base64_decode($bd['filename']) : $bd['filename'];
                        // 进行编码转换 会出现未知bug
//                        if($charset && strtolower($charset) != 'utf-8' && strtolower($charset) != 'utf8'){
//                            $data['body'][$bdk]['name'] = @iconv($charset,'utf-8',$data['body'][$bdk]['name']);
//                            $data['body'][$bdk]['filename'] = @iconv($charset,'utf-8',$data['body'][$bdk]['filename']);
//                        }

                        $data['body'][$bdk]['size'] = 0;
                        $data['body'][$bdk]['url'] = '';
                        if(is_file($bd['path'])){
                            // 文件大小
                            $data['body'][$bdk]['size'] = filesize($bd['path']);
                            // 文件访问地址
                            $data['body'][$bdk]['url'] = APP_HOST.str_replace(PUBLIC_PATH,'',$bd['path']);
                        }

                        // 验证编码是否有其他编码字符,这里编辑了未知编码
                        if(!@json_encode($data['body'][$bdk])){
                            // 抛弃原有的名字,显示已存储到服务器的名字
                            $data['body'][$bdk]['name'] = $data['body'][$bdk]['signName'];
                            $data['body'][$bdk]['filename'] = $data['body'][$bdk]['signName'];
                        }

                        unset($data['body'][$bdk]['path']);

                        // 内容区是有有cid
                        if ($htmlbody && !empty($bd['content-id'])){
                            if(!strpos($htmlbody,"\"cid:{$bd['content-id']}\"")){
                                unset($data['body'][$bdk]['content-id']);
                            }
                        }
                        // 没有html内容,content-id是不可能有的
                        else if(!$htmlbody){
                            unset($data['body'][$bdk]['content-id']);
                        }
                    }
                }
                return [
                    'data'  =>  $data
                ];
            }// 草稿
            else if(!$data['uid'] && $data['draft']){
                $data['body'] = [];
                return [
                    'data'  =>  $data
                ];
            }

            // 循环几次
            if($data['uid']&&$sync_num < 1){
                $folder = db()->value(folderSql::first(['id'=>$data['folder_id']],'origin_folder'));
                try{
                    (new SyncMail($data['email_id']))->mail($folder,[$data['uid']],true);
                }catch (\Throwable $e){
                    app()->e('邮箱登录验证异常');
                }

                $sync_num++;
                $reload = 0;
                goto HOME_INFO_BODY;
            }
            logs('超过读取body次数 '.$data['id']);

        }else{
            logs('读取body 没有查询到数据 '.$id.'-'.($email['email']??''));
        }

        app()->e('mail_body_error');

    }


    /**
     * 解析订阅数据
     * @author:dc
     * @time 2024/8/7 14:12
     */
    public function desubscribe(){
        $key = app()->request('key','');
        app()->_json(MailFun::deSubscribeUrl($key));
    }

}