<?php

namespace App\Http\Controllers\API\Chat;

use Illuminate\Http\Request;
use Image;
use Validator;

use App\Http\Controllers\API\ApiController;
use App\Http\Traits\FileSystemTrait;
use App\Models\Group;
use App\Models\Message;
use App\Repositories\MessageRepository;

/**
 * Class Messages
 *
 * @package App\Http\Controllers\API\Chat
 */
class Messages extends ApiController
{

    use FileSystemTrait;

    /**
     * Returns messages list from a group
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        $groupMessages = MessageRepository::instance()->getGroupMessages($request);

        $messages = [];
        foreach ($groupMessages as $groupMessage) {
            $messages[] = $groupMessage->apiOutputData();
        }

        return $this->response
            ->setResponse([
                'currentPage'  => $groupMessages->currentPage(),
                'hasMorePages' => $groupMessages->hasMorePages(),
                'nextPage'     => $groupMessages->nextPageUrl(),
                'perPage'      => $groupMessages->perPage(),
                'previousPage' => $groupMessages->previousPageUrl(),
                'messages'     => $messages
            ])
            ->setSuccess(true)
            ->toJson();
    }

    /**
     * Store the message
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function sendMessage(Request $request)
    {
        $errors = Validator::make($request->all(), [
            'groupid' => 'required|numeric',
            'file'    => 'file'
        ])->messages();

        $message = null;

        if (0 === count($errors->all())) {
            $group = ($request->has('groupid')) ? Group::find($request->get('groupid')) : null;

            // Check if user sending message is in the group
            if (null !== $group && $group->users->contains($this->user)) {
                // Save message
                $message = $this->saveMessage($request, $group);

                $this->response->setMessage([
                    'type' => 'success',
                    'text' => trans('messages.message_sent_successfully')
                ]);
            } else {
                $errors->add('message_sent_failed', trans('messages.message_sent_failed'));
            }
        }

        return $this->response
            ->setResponse([
                'message' => (null !== $message) ? $message->apiOutputData() : null
            ])
            ->setSuccess((0 === count($errors->all())) ? true : false)
            ->setErrors($errors)
            ->toJson();
    }

    /**
     * Save message
     *
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\Group        $group
     * @return \App\Models\Message
     */
    protected function saveMessage(Request $request, Group $group)
    {
        $message = new Message();
        $message->text = $request->get('text', null);
        $message->user()->associate($this->user->oid);
        $message->group()->associate($group->oid);
        if (null !== $file = $this->handleFiles($request, $group)) {
            $message->file = $file->getFilename();
            $message->file_original_name = $request->file('file')->getClientOriginalName();
        }
        $message->save();

        return $message;
    }

    /**
     * Handle files
     *
     * @param \Illuminate\Http\Request $request
     * @param \App\Models\Group        $group
     * @return \Illuminate\Http\File|null
     */
    protected function handleFiles(Request $request, Group $group)
    {
        $file = null;

        if ($request->hasFile('file') && $request->file('file')->isValid()) {
            // Create, if not exists, directory for files sent in group
            $fileGroupDirPath = Message::getGroupDirPath($group->oid);
            FileSystemTrait::makeDirectory($fileGroupDirPath);

            // Get file from post and upload on server
            $file = FileSystemTrait::uploadFileToStorage($fileGroupDirPath, $this->user->oid, $request->file('file'));
        }

        return $file;
    }

    /**
     * Get smaller version of the image
     *
     * @param int    $group
     * @param int    $height
     * @param string $filename
     * @return mixed
     */
    public function getSmallerImage(Request $request, $customerid, $group, $height, $filename)
    {
        $filename = Message::getGroupDirPath($group, $customerid) . '/' . $filename;

        $img = Image::make($filename)->orientate();
        $img->resize(null, $height, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });

        return $img->response();
    }
}