<?php


namespace Lib\Imap\Request;

use Lib\Imap\Imap;
use Lib\Imap\ImapSearch;
use Lib\Imap\Parse\Body as ParseBody;
use Lib\Imap\Parse\MessageItem;
use Lib\Imap\Parse\Messager;

/**
 * 登录
 * @author:dc
 * @time 2024/9/13 17:09
 * Class Login
 * @package Lib\Imap\Request
 */
class Msg extends Request{

    /**
     * @var Folder
     */
    public Folder $folder;

    /**
     * 读取列表条件
     * @var array
     */
    protected array $number = [];


    /**
     * 是否是uid
     * @var bool
     */
    private bool $isUid = false;


    public function __construct(Imap $imap, Folder $folder)
    {
        parent::__construct($imap);

        $this->folder = $folder;
    }


    public function exec(): static{return $this;}



    /**
     * 分页读取
     * @param int $p
     * @param int $limit
     * @return $this
     * @author:dc
     * @time 2024/9/14 14:06
     */
    public function forPage(int $p=1, int $limit=20):static {
        $this->msgno(range(($p-1)*$limit+1,$p*$limit));
        return $this;
    }

    /**
     * 使用uid进行查询
     * @param array|int $uids
     * @return $this
     * @author:dc
     * @time 2024/9/14 14:06
     */
    public function uid(array|int $uids):static {
        $this->isUid = true;
        $this->number =   is_array($uids) ? $uids : [$uids];
        return $this;
    }

    /**
     * 使用编号进行查询
     * @param array|int $msgno
     * @return $this
     * @author:dc
     * @time 2024/9/14 14:06
     */
    public function msgno(array|int $msgno):static {
        $this->isUid = false;
        $this->number =   is_array($msgno)?$msgno:[$msgno];
        return $this;
    }

    /**
     * 搜索
     * @param ImapSearch $search
     * @return $this
     * @author:dc
     * @time 2024/9/14 15:48
     */
    public function search(ImapSearch $search):static {
        $this->folder->exec(); // 防止在其他文件夹下面
        $this->cmd("UID SEARCH %s",$search->toString());
        $uids = [];
        foreach ($this->result as $item){
            // 匹配uid * SEARCH 2 84 882
            if(preg_match("/^\* SEARCH ([0-9\s]{1,})$/i",$item,$m)){
                $uids = array_merge($uids,explode(' ',$m[1]));
            }
        }
        $this->uid($uids);
        return $this;
    }


    /**
     * 读取邮件列表
     * @return Messager
     * @author:dc
     * @time 2024/9/14 15:34
     */
    public function get():Messager{
        $this->folder->exec(); // 防止在其他文件夹下面
        $this->cmd(
            "%sFETCH %s (UID FLAGS INTERNALDATE RFC822.SIZE BODYSTRUCTURE RFC822.HEADER)",
            $this->isUid?'UID ':'',
            implode(',',$this->number)
        );

        return new Messager($this->result, $this);
    }


    /**
     * 读取body 体
     * @param MessageItem $msg
     * @return ParseBody
     * @author:dc
     * @time 2024/9/20 17:09
     */
    public function getBody(MessageItem $msg):ParseBody {
        $this->folder->exec(); // 防止在其他文件夹下面

        $this->cmd("UID FETCH %s (RFC822.TEXT)", $msg->uid);

        return (new ParseBody(implode('',$this->result),$msg->header));

    }


    /**
     * 添加/删除 标签
     * @param string $flag
     * @param bool $unset
     * @return bool
     * @author:dc
     * @time 2024/9/24 9:51
     */
    public function setFlags(string $flag, bool $unset = false):bool {
        // FLAGS.SILENT 和 FLAGS 前者不返回新的标签 后者返回新的标签列表
        // UID STORE 1 +FLAGS (\Seen) 这个是添加为已读
        // UID STORE 1 -FLAGS (\Seen) 这个是标记为未读
        $this->cmd("%sSTORE %s %sFLAGS.SILENT (\%s)",
            $this->isUid ? 'UID ' : '',
            implode(',',$this->number),
            $unset ? '-' : '+',
            $flag
        );
        return $this->isOk();
    }



    /**
     * 标记为删除
     * @return bool
     * @author:dc
     * @time 2024/9/18 11:52
     */
    public function deleted():bool {
        return $this->setFlags('\Deleted');
    }

    /**
     * 取消删除标记
     * @return bool
     * @author:dc
     * @time 2024/9/24 9:57
     */
    public function undeleted():bool {
        return $this->setFlags('\Deleted',true);
    }

    /**
     * 标记为 已读
     * @return bool
     * @author:dc
     * @time 2024/9/18 17:53
     */
    public function seen():bool {
        return $this->setFlags('\Seen');
    }

    /**
     * 未读
     * @return bool
     * @author:dc
     * @time 2024/9/24 9:58
     */
    public function unseen():bool {
        return $this->setFlags('\Seen',true);
    }

    /**
     * 标记为 草稿
     * @return bool
     * @author:dc
     * @time 2024/9/18 17:53
     */
    public function draft():bool {
        return $this->setFlags('\Draft');
    }

    public function undraft():bool {
        return $this->setFlags('\Draft',true);
    }

    /**
     * 标记为 星标
     * @return bool
     * @author:dc
     * @time 2024/9/18 17:53
     */
    public function flagged():bool {
        return $this->setFlags('\Flagged');
    }

    /**
     * 取消星标
     * @return bool
     * @author:dc
     * @time 2024/9/24 9:59
     */
    public function unflagged():bool {
        return $this->setFlags('\Flagged',true);
    }

    /**
     * 标记为已回复
     * @return bool
     * @author:dc
     * @time 2024/9/18 17:52
     */
    public function answered():bool {
        return $this->setFlags('\Answered');
    }

    /**
     * 取消标记 已回复
     * @return bool
     * @author:dc
     * @time 2024/9/24 10:00
     */
    public function unanswered():bool {
        return $this->setFlags('\Answered',true);
    }

    /**
     * 标记为最近
     * @return bool
     * @author:dc
     * @time 2024/9/18 17:54
     */
    public function recent():bool {
        return $this->setFlags('\recent');
    }

    /**
     * 取消最近标记
     * @return bool
     * @author:dc
     * @time 2024/9/24 10:01
     */
    public function unrecent():bool {
        return $this->setFlags('\recent',true);
    }


    /**
     * 移动邮件 到指定目录
     * @param string $folder
     * @param bool $utf7
     * @return bool
     * @author:dc
     * @time 2024/9/24 10:47
     */
    public function move(string $folder, bool $utf7 = true):bool {
        if(!$utf7) $folder = mb_convert_encoding($folder,"UTF7-IMAP","UTF-8");
//        "UID MOVE {$uids} \"{$folder}\""
        $this->cmd('%s MOVE %s "%s"',
            $this->isUid?'UID ':'',
            implode(',',$this->number),
            $folder
        );

        return $this->isOk();
    }

    /**
     * 复制邮件到指定目录
     * @param string $folder 目标文件夹
     * @param bool $utf7 是否已转码
     * @return bool
     * @author:dc
     * @time 2024/9/24 10:51
     */
    public function copy(string $folder, bool $utf7 = true):bool {
        if(!$utf7) $folder = mb_convert_encoding($folder,"UTF7-IMAP","UTF-8");
//        "UID COPY {$uids} \"{$folder}\""
        $this->cmd('%s COPY %s "%s"',
            $this->isUid?'UID ':'',
            implode(',',$this->number),
            $folder
        );

        return $this->isOk();

    }




}