<?php

namespace Mtc\Plugins\Clinic\Http\Controllers\Admin;

use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Mtc\Core\Admin\User;
use Mtc\Core\AdminUser;
use Mtc\Core\PaginationTemplate;
use Mtc\Plugins\Clinic\Src\Logger;
use Mtc\Plugins\Clinic\Src\Models\Review;
use Mtc\Plugins\Clinic\Src\Models\ReviewType;
use Mtc\Shop\Assessment\Answer;
use Mtc\Shop\Assessment\Assessment;
use Mtc\Shop\Assessment\Form;
use Mtc\Shop\Category;

/**
 * Class ReviewController
 */
class ReviewController extends ClinicController
{

    const PER_PAGE = 20;

    /**
     * List of database entries
     *
     * @param Request $request
     * @return string
     */
    public function index(Request $request): string
    {
        $title = 'Manage Reviews';
        $page_meta['title'] = config('app.name') . ' | ' . $title;
        $page = $request->input('page') ?: 1;

        $reviews = Review::query()
            ->with('member.addressBilling')
            ->with('category')
            ->with('form')
            ->with('user')
            ->orderByDesc('due_date');
        $reviews = Review::filterReviews($reviews, $request->all());

        $pagination = new PaginationTemplate([
            'item_count' => $reviews->count(),
            'per_page' => self::PER_PAGE,
            'active_page' => $page,
            'show_view_all' => false,
            'page_url' => route('admin-reviews', [], false),
        ]);
        $pagination = $pagination->render();

        return template('admin/reviews/index.twig', [
            'page_meta' => $page_meta,
            'title' => $title,
            'mediums' => Review::$mediums,
            'types' => Review::$types,
            'categories' => Category::getCompleteFlatTree(),
            'statuses' => Review::$statuses,
            'users' => AdminUser::query()
                ->orderBy('name')
                ->get(),
            'forms' => Form::query()
                ->orderBy('name')
                ->get(),
            'reviews' => $reviews->take(self::PER_PAGE)->offset(($page - 1) * self::PER_PAGE)->get()
                ->map(function (Review $review) {
                    $review->due_date = Carbon::parse($review->due_date)
                        ->format('d/m/Y');
                    return $review;
                }),
            'reviewTypes' => ReviewType::query()
                ->with('form')
                ->with('category')
                ->orderBy('name')
                ->get(),
            'request' => $request->all(),
            'pagination' => $pagination,
        ]);
    }

    /**
     * Load reviews
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function load(Request $request): JsonResponse
    {
        $reviews = Review::query()
            ->with('member.addressBilling')
            ->with('category')
            ->with('form')
            ->with('user')
            ->orderByDesc('due_date');

        return response()
            ->json([
                'reviews' => Review::filterReviews($reviews, $request->all())
                    ->get()->map(function (Review $review) {
                        $review->due_date = Carbon::parse($review->due_date)
                            ->format('d/m/Y');
                        $review->medium = Review::$mediums[$review->medium];
                        $review->type = Review::$types[$review->type];
                        $review->status = Review::$statuses[$review->status];
                        return $review;
                    }),
            ]);
    }

    /**
     * Load single review
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function loadReview(Request $request): JsonResponse
    {
        $review = new Review();
        $lastReview = null;
        if (!empty($request->input('id'))) {
            /** @var Review $review */
            $review = Review::query()
                ->with('member.addressBilling')
                ->with('assessments.answers.question')
                ->with('assessments.form')
                ->with('assessments.orderItems')
                ->find($request->input('id'));
            $review->due_date = Carbon::parse($review->due_date)
                ->format('d/m/Y');

            $review->assessments
                ->map(function (Assessment $assessment) {
                    $assessment->answers
                        ->map(function (Answer $answer) {
                            $answer->getDetails();
                            $answer->html = template('admin/assessments/assessmentAnswer.twig', [
                                'answer' => $answer,
                            ]);
                            return $answer;
                        });
                    return $assessment;
                });
        } else {
            $lastReview = Review::query()
                ->orderByDesc('due_date')
                ->first();
        }

        return response()
            ->json([
                'mediums' => Review::$mediums,
                'types' => Review::$types,
                'categories' => Category::getCompleteFlatTree(),
                'statuses' => Review::$statuses,
                'users' => AdminUser::query()
                    ->orderBy('name')
                    ->get(),
                'forms' => Form::query()
                    ->orderBy('name')
                    ->get(),
                'reviewTypes' => ReviewType::query()
                    ->with('form')
                    ->with('category')
                    ->orderBy('name')
                    ->get(),
                'dateOptions' => Review::getDateOptions(),
                'review' => $review,
                'lastReview' => $lastReview,
            ]);
    }

    /**
     * Add / edit page
     *
     * @param $id
     * @return string
     */
    public function edit($id = null): string
    {
        $title = !empty($id) ?
            'Edit Review' :
            'Add Review';
        $page_meta['title'] = config('app.name') . ' | ' . $title;

        return template('admin/reviews/edit.twig', [
            'page_meta' => $page_meta,
            'title' => $title,
            'reviewID' => $id,
            'routes' => [
                'admin-reviews-store' => route('admin-reviews-store'),
                'admin-patients-search' => route('admin-patients-search'),
                'admin-patients-profile' => route('admin-patients-profile', [
                    'id' => '---id---',
                ]),
                'admin-reviews-load-review' => route('admin-reviews-load-review'),
            ],
        ]);
    }

    /**
     * Creates / updates entry in database
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function store(Request $request): JsonResponse
    {
        if ($errors = Review::validate($request->all())) {
            return response()
                ->json([
                    'errors' => $errors,
                ]);
        }

        /** @var Review $review */
        $review = Review::query()
            ->findOrNew($request->input('id'));

        $action = empty($weightTrack->id) ?
            Logger::ACTION_CREATED :
            Logger::ACTION_UPDATED;

        $data = $request->all();
        $data['due_date'] = Carbon::createFromFormat('d/m/Y', $data['due_date'])
            ->format('Y-m-d');

        $review->fill($data);
        if (empty($review->hash)) {
            $review->generateHash();
        }
        $review->save();

        (new Logger($review, User::getAdminUser(), $request->input('member_id')))
            ->log(Logger::REVIEW, $action, $review->toArray());

        $review->due_date = $request->input('due_date');

        return response()
            ->json([
                'success' => 'Data saved successfully!',
                'review' => $review,
            ]);
    }

}
