<?php

namespace App\Http\Controllers;

use App\Http\Middleware\SNCheckServerMiddleware;
use App\Mail\ReportSummaryMail;
use App\Models\SerialNumberCheck;
use App\Models\SerialNumberCheckTracking;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;

class SerialNumberCheckController extends Controller
{
    protected $isValid = true;

    public function __construct()
    {
        $this->middleware('auth')->except([
            'apiUpdateComplete'
        ]);

        $this->middleware(SNCheckServerMiddleware::class)->only([
            'apiUpdateComplete'
        ]);
    }

    protected function saveTracking(SerialNumberCheck $serialNumberCheck, int $usePoint, $response = null)
    {
        $user = auth()->user();
        $serialNumberCheck->tracking()->create([
            'serial_number_check_id' => $serialNumberCheck->id,
            'current_point' => $user->point,
            'use_point' => $usePoint,
            'response' => $response,
        ]);
        // update point user
        $user->point = (int) $user->point - $usePoint;
        $user->save();
    }

    public function index()
    {
        return view('client.pages.sn_check.SN_check');
    }

    public function search(Request $request)
    {
        $this->validate($request, [
            'keyword' => 'required|array',
            'keyword.*' => 'string|min:6|max:25',
        ], [
            'min' => "Serial length ranges from 6 to 25 characters.<br>Please check serial number!",
            'max' => "Serial length ranges from 6 to 25 characters.<br>Please check serial number!"
        ]);

        // Formula for calculating points: point - count(keyword)
        $countKeyword = count($request->input('keyword'));
        $currentPoint = (int) auth()->user()->point;
        $remainPoint = ($currentPoint - $countKeyword);

        if ($remainPoint < 0) {
            return response()->json([
                'status' => false,
                'message' => 'Your point is not enough!'
            ], 403);
        }

        try {
            $serialNumberCheck = new SerialNumberCheck;
            DB::transaction(function () use ($request, &$serialNumberCheck, $countKeyword) {
                $serialNumberCheck->keyword = $request->input('keyword');
                $serialNumberCheck->user_id = auth()->id();
                $serialNumberCheck->save();
                $this->saveTracking($serialNumberCheck, $countKeyword);
            });

            DB::commit();
            return response()->json([
                'status' => true,
                'message' => "$countKeyword keyword(s) are being searched, your remain point is $remainPoint.",
                'keyword' => $request->input('keyword'),
                'user' => auth()->user()->only([
                    'point'
                ]),
                'serial_number_check' => $serialNumberCheck
            ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return response()->json([
                'status' => false,
                'message' => $th->getMessage(),
                'line' => $th->getLine(),
                'file' => $th->getFile()
            ], 500);
        }
    }

    public function apiUpdateComplete(Request $request)
    {
        $this->validate($request, [
            'checkId' => [
                'required',
                'exists:serial_number_check,id'
            ],
            'response.data' => 'array'
        ]);

        $serialNumberCheck = SerialNumberCheck::find(
            $request->input('checkId')
        );

        if ($serialNumberCheck->status !== SerialNumberCheck::STATUS_PENDING) {
            return response()->json([
                'status' => false,
                'message' => "This serial number was completed or failed, Please don't call again!"
            ], 400);
        }

        // save data
        try {
            $serialNumbersResponse = collect($request->input('response.data'))->pluck('_serialNumber');
            $keywordMismatch = collect($serialNumberCheck->keyword)
                ->diff($serialNumbersResponse);
            DB::transaction(function () use ($request, &$serialNumberCheck, $keywordMismatch) {
                $serialNumberCheck->response = $request->input('response');
                $serialNumberCheck->status = SerialNumberCheck::STATUS_COMPLETE;
                $serialNumberCheck->save();

                // login by serialNumberCheck
                auth()->loginUsingId($serialNumberCheck->user_id);
                $this->saveTracking($serialNumberCheck, -count($keywordMismatch), $request->input('response'));
            });

            DB::commit();
            return response()->json([
                'status' => true,
                'user' => auth()->user(),
                'serialNumbersMismatch' => $keywordMismatch
            ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return response()->json([
                'status' => false,
                'message' => $th->getMessage(),
                'line' => $th->getLine(),
                'file' => $th->getFile()
            ], 500);
        }
    }

    public function sendReportSummary(Request $request)
    {
        $data = json_decode($request->input('html_content'), true);
        // dd($data);
        if($data){
            Mail::to(auth()->user()->email)->send(new ReportSummaryMail($data));
            return response()->json(['status'=>true, 'message' => 'The report has been sent successfully!'], Response::HTTP_OK);
        }

        return response()->json([
            'status' => false,
            'message' => "The report has been sent failed!"
        ], 400);
    }
}
