<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

class MailMessage extends Model
{
    protected $table = 'mail_messages';

    protected $guarded = [];

    protected $casts = [
        'from' => 'array',
        'to' => 'array',
        'cc' => 'array',
        'bcc' => 'array',
        'reply_to' => 'array',
        'attachments' => 'array',
        'flags' => 'array',
    ];

    public static function getLatestDateTime($mailId)
    {
        $message = static::where('mail_id', $mailId)->orderBy('date', 'desc')->first();

        if (is_null($message)) {
            return Carbon::now()->subDays(3);
        }

        return $message->date;
    }

    public static function writeIn($mailId, \Webklex\PHPIMAP\Message $message)
    {
        if (static::where('mail_id', $mailId)->where('uid', $message->getUid())->exists()) {
            return false;
        }

        return static::create([
            'mail_id' => $mailId,
            'uid' => $message->getUid(),
            'subject' => $message->getSubject(),
            'from' => $message->getFrom()->first(),
            'to' => $message->getTo()->first(),
            'cc' => $message->getCc() ? $message->getCc()->first() : [],
            'bcc' => $message->getBcc() ? $message->getBcc()->first() : [],
            'reply_to' => $message->getReplyTo()? $message->getReplyTo()->first() : '',
            'body' => $message->hasHTMLBody() ? $message->getHTMLBody() : $message->getTextBody(),
            'attachments' => static::parseAttachments($message),
            'flags' => $message->getFlags(),
            'date' => $message->getDate()->first()->toDateTimeString(),
        ]);
    }

    public static function parseAttachments($message)
    {
        $tmpAttachments = [];
        if ($message->hasAttachments()) {
            $attachments = $message->getAttachments();
            foreach ($attachments as $attachment) {
                $tmpAttachments[] = [
                    'name' => $attachment->getName(),
                    'type' => $attachment->getType(),
                    'size' => $attachment->getSize(),
                    'content' => $attachment->getContent()
                ];
            }
        }

        return $tmpAttachments;
    }

    public function getAttachmentByName($filename)
    {
        $attachments = $this->attachments;

        foreach ($attachments as $attachment) {
            if ($attachment['name'] == $filename) {
                $headers = [
                    'Content-Type' => 'application/octet-stream',
                    'Content-Disposition' => 'attachment; filename="'. $filename. '"',
                    'Accept-ranges' => 'bytes',
                    'Content-Length' => $attachment['size']
                ];

                return response()->make($attachment['content'], 200, $headers);
            }
        }
    }

    public static function seen($mailMessage)
    {
        if (isset($mailMessage->flags['seen'])) {
            return false;
        }

        $mail = Mail::where('id', $mailMessage->mail_id)->first();

        $client = $mail->getMailBoxClient();
        $client->connect();

        $folder = $client->getFolder('INBOX');
        if (is_null($folder)) {
            $folder = $client->getFolder('Inbox');
        }

        $message = $folder->query()->getMessageByUid($mailMessage->uid);

        $message->setFlag('Seen');
        $mailMessage->update([
            'flags' => array_merge($mailMessage->flags, ['seen' => 'Seen'])
        ]);
    }
}
