<?php

namespace App\Http\Controllers\Admin;

use Exception;
use App\Models\Mail;
use App\Models\MailMessage;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class MailMessageController extends Controller
{
    public function index(Request $request)
    {
        $size = $request->input('perPage', 15);
        $mails = Mail::all();
        $email = $request->input('email');

        $mail = $email ? $mails->where('email', $email)->first() : $mails->where('is_default', 1)->first();
        if (is_null($mail)) {
            return redirect()->route('admin.email.bind');
        }

        $query = MailMessage::where('mail_id', $mail ? $mail->id : 0)->where('is_deleted', 0)->where('is_sent', 0);
        $messages = $query->paginate($size);

        return view('admin.email.inbox', compact('messages', 'mails', 'mail'));
    }

    public function drafts()
    {
        return view('admin.email.drafts');
    }

    public function trash(Request $request)
    {
        $size = $request->input('perPage', 15);
        $mails = Mail::all();
        $email = $request->input('email');

        $mail = $email ? $mails->where('email', $email)->first() : $mails->where('is_default', 1)->first();

        $query = MailMessage::where('mail_id', $mail ? $mail->id : 0)->where('is_deleted', 1);
        $messages = $query->paginate($size);

        return view('admin.email.trash', compact('messages', 'mails', 'mail'));
    }

    public function sent(Request $request)
    {
        $size = $request->input('perPage', 15);
        $mails = Mail::all();
        $email = $request->input('email');

        $mail = $email ? $mails->where('email', $email)->first() : $mails->where('is_default', 1)->first();

        $query = MailMessage::where('mail_id', $mail ? $mail->id : 0)->where('is_sent', 1);
        $messages = $query->paginate($size);

        return view('admin.email.sent', compact('messages', 'mails', 'mail'));
    }

    public function show($id, Request $request)
    {
        $on = $request->input('on');
        $message = MailMessage::find($id);

        if (isset($on) and $on == 'inbox') {
            // 强制已读
            MailMessage::seen($message);
        }
        $mails = Mail::all();
        $mail = $mails->where('id', $message->mail_id)->first();
        $on = 'inbox';
        if ($message->is_sent){
            $on = 'sent';
        }
        if ($message->is_deleted) {
            $on = 'trash';
        }
        return view('admin.email.detail', compact('message', 'mails', 'mail', 'on'));
    }

    public function show_iframe($id)
    {
        $message = MailMessage::find($id);
        return view('admin.email.detail_black', compact('message'));
    }

    // 发信
    public function send(Request $request)
    {
        $mail = Mail::where('email', $request->input('email'))->first();

        if (is_null($mail)) {
            throw new Exception('无效的邮箱');
        }

        $transport = (new \Swift_SmtpTransport($mail->smtp_host, $mail->smtp_port, 'ssl'))
            ->setUsername($mail->email)
            ->setPassword($mail->password);

        $subject = $request->input('subject');
        $from = [$mail->email];
        $to = $request->input('to');
        $cc = $request->input('cc', []);
        $bcc = $request->input('bcc', []);
        $body = $request->input('body');

        $message = (new \Swift_Message($subject))
            ->setFrom($from)
            ->setBody($body, 'text/html');

        foreach ($to as $address) {
            $message->setTo($address);
        }
        foreach ($cc as $address) {
            $message->setCc($address);
        }
        foreach ($bcc as $address) {
            $message->setBcc($address);
        }

        $attachments = $request->input('attachments', []);

        foreach ($attachments as $attachment) {
            $message->attach(\Swift_Attachment::fromPath('https:'. $attachment['path']));
        }

        $mailer = new \Swift_Mailer($transport);

        $result = $mailer->send($message);

        if ($result) {
            MailMessage::create([
                'mail_id' => $mail->id,
                'uid' => 0,
                'subject' => $subject,
                'from' => $from,
                'to' => $to,
                'cc' => $cc,
                'bcc' => $bcc,
                'reply_to' => $from,
                'attachments' => $attachments,
                'body' => $body,
                'is_sent' => 1
            ]);

            return response()->json(['status' => 'success', 'message' => '发送成功']);
        } else {
            return response()->json(['status' => 'error', 'message' => '发送失败']);
        }
    }

    // 收信
    public function receive(Request $request)
    {
        try {
            $mail = Mail::where('email', $request->input('email'))->first();

            if (is_null($mail)) {
                throw new Exception('无效的邮箱');
            }

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

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

            $count = $query->since(MailMessage::getLatestDateTime($mail->id))->count();

            for ($page = 1; $page <= ceil($count / 10); $page++) {
                $limit = $page == ceil($count / 10) ? $count % 10 : 10;
                $messages = $query->all()->limit($limit, $page)->get();

                foreach ($messages as $message) {
                    MailMessage::writeIn($mail->id, $message);
                }
            }
        } catch (Exception $e) {
            return response()->json(['status' => 'error', 'message' => $e->getMessage()]);
        }

        return response()->json(['status' => 'success']);
    }

    public function read($id)
    {
        try {
            $mailMessage = MailMessage::where('id', $id)->first();
            if (is_null($mailMessage)) {
                throw new Exception('邮件不存在');
            }

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

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

            $folder = $client->getFolder('INBOX');

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

            if (isset($mailMessage->flags['seen'])) {
                $message->unsetFlag('Seen');
                unset($mailMessage->flags['seen']);
                $mailMessage->update([
                    'flags' => $mailMessage->flags
                ]);
            } else {
                $message->setFlag('Seen');
                $mailMessage->update([
                    'flags' => array_merge($mailMessage->flags, ['seen' => 'Seen'])
                ]);
            }

            return response()->json(['status' => 'success']);
        } catch (Exception $e) {

            return response()->json(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }

    public function download(Request $request, $id)
    {
        $mailMessage = MailMessage::where('id', $id)->first();
        if (is_null($mailMessage)) {
            throw new Exception('邮件不存在');
        }
        $name = $request->input('name');

        return $mailMessage->getAttachmentByName($name);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param Request $request
     * @param int $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function destroy(Request $request, $id)
    {
        try {
            $mailMessage = MailMessage::where('id', $id)->first();
            if (is_null($mailMessage)) {
                throw new Exception('邮件不存在');
            }

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


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

                $folder = $client->getFolder('INBOX');
                $message = $folder->query()->getMessageByUid($mailMessage->uid);

                if ($request->input('force')) {
                    $message->delete(true);
                } else {
                    $message->delete(false);
                }
            }

            if ($request->input('force')) {
                $mailMessage->delete();
            } else {
                $mailMessage->update([
                    'is_deleted' => 1
                ]);
            }

            return response()->json(['status' => 'success']);
        } catch (Exception $e) {

            return response()->json(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }
}
