<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Mail;
use App\Models\UserMail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Validator;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index(Request $request)
    {
        $is_read = $request->input('is_read', -1);
        $mail    = $request->input('mail', '');
        $where   = [
            'user_id' => $request->user()->id,
        ];
        if ($is_read != -1) {
            $where['is_read'] = intval($is_read);
        }
        if (!empty($mail)) {
            $where['to_hash'] = hash('sha256', $mail);
        }

        $mail_list = Mail::where($where)
            ->select([
                'id as key',
                'from',
                'to',
                'title',
                'received_at',
                'created_at',
            ])
            ->orderBy('received_at', 'asc')
            ->paginate(20)
            ->withQueryString();
        foreach ($mail_list as $value) {
            // $value->hash = hash('sha256', $value->key . $value->to . $value->received_at . $value->created_at);
            $value->key = Crypt::encryptString($value->key);
        }
        $total = Mail::where($where)->count();

        $mail_address_list = UserMail::where(['user_id' => $request->user()->id, 'is_disable' => 0])->get();
        return view('home.index', [
            'mail_list'         => $mail_list,
            'mail_address_list' => $mail_address_list,
            'total'             => $total,
        ]);
    }

    public function total(Request $request)
    {
        $is_read = $request->input('is_read', -1);
        $mail    = $request->input('mail', '');
        $where   = [
            'user_id' => $request->user()->id,
        ];
        if ($is_read != -1) {
            $where['is_read'] = intval($is_read);
        }
        if (!empty($mail)) {
            $where['to_hash'] = hash('sha256', $mail);
        }
        $total = Mail::where($where)->count();
        return response()->json([
            'code' => 200,
            'msg'  => "success",
            'data' => [
                'total' => $total,
                // 'where' => $where,
            ],
        ]);
    }

    public function info(Request $request, $key)
    {
        try {
            $id = Crypt::decryptString($key);
        } catch (\Throwable $th) {
            return abort(400);
        }

        if (empty(intval($id))) {
            return abort(400);
        }

        $mail_info = Mail::find($id);
        if (empty($mail_info) || $mail_info->user_id != $request->user()->id) {
            return abort(404);
        }

        $mail_info->is_read = 1;
        $mail_info->save();

        $title = str_replace(["\n", "\r", "\t"], '', strip_tags($mail_info->title));
        $body  = preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', "", $mail_info->body);

        return response()->json([
            'code' => 1,
            'msg'  => '',
            'data' => [
                'from'        => $mail_info->from,
                'title'       => base64_encode($title),
                'body'        => base64_encode($body),
                'created_at'  => $mail_info->created_at,
                'received_at' => $mail_info->received_at,
            ],
        ]);

    }

    public function address(Request $request)
    {
        $domain_list  = config('mail.domain_list');
        $block_prefix = config('mail.block_prefix');

        $private_limit = config('mail.private_limit');

        if ($request->isMethod('post')) {
            $prefix       = $request->input('prefix', '');
            $domain       = $request->input('domain', '');
            $mail_address = "{$prefix}@{$domain}";

            $validator = Validator::make(['email' => $mail_address], [
                'email' => [
                    'required',
                    'email',
                    function ($attribute, $value, $fail) {
                        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
                            return $fail('输入的邮箱地址无效.');
                        }

                        list($prefix, $domain) = explode('@', $value);
                        $length                = mb_strlen($prefix);

                        if ($length < 5 || $length > 32) {
                            return $fail('邮箱前缀必须在5~32个字符之间');
                        }

                        if (in_array($prefix, config('mail.block_prefix'))) {
                            return $fail('此前缀已被禁止使用.');
                        }
                    },
                ],
            ]);

            if ($validator->fails()) {
                toastr()->error($validator->errors()->first());
                return redirect()->back();
            }

            if (UserMail::where('user_id', $request->user()->id)->count() >= $private_limit) {
                toastr()->error('私人邮箱数量已达上限.');
                return redirect()->back();
            }

            $mail_hash = hash('sha256', $mail_address);
            if (UserMail::where('mail_hash', $mail_hash)->count() != 0) {
                toastr()->error('此邮箱已被其它用户使用.');
                return redirect()->back();
            }

            if (Mail::where('to_hash', $mail_hash)->count() != 0) {
                toastr()->error('此邮箱无法被设置为私人邮箱.');
                return redirect()->back();
            }

            $user_mail            = new UserMail;
            $user_mail->user_id   = $request->user()->id;
            $user_mail->mail      = $mail_address;
            $user_mail->mail_hash = $mail_hash;
            $user_mail->save();

            toastr()->success('私人邮箱已创建.');
        }

        $mail_address_list = UserMail::where(['user_id' => $request->user()->id, 'is_disable' => 0])->get();
        return view('home.address', [
            'mail_address_list' => $mail_address_list,
            'domain_list'       => $domain_list,
            'block_prefix'      => $block_prefix,
            'private_limit'     => $private_limit,
        ]);
    }
}
