<?php

namespace App\Http\Controllers;

use App\Marker;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;

class MarkerController extends Controller
{

/**
 * @apiDefine Header
 * @apiHeader {String} Authorization Bearer + token
 * @apiHeaderExample Authorization header example
 * Authorization: Bearer eyJ0eXAiO.iJKV1QiLCJhb.GciOiJIUzI1NiJ9
 */

 /**
  * @apiDefine JWTErrors
  * @apiError TokenNotProvided Token not provided.
  * @apiErrorExample TokenNotProvided response:
  *     HTTP/1.1 401 Unauthorized
  *     {
  *       "error": "Token not provided."
  *     }
  *
  * @apiError ExpiredToken Provided token is expired.
  * @apiErrorExample ExpiredToken response:
  *     HTTP/1.1 400 Bad Request
  *     {
  *       "error": "Provided token is expired."
  *     }
  *
  * @apiError DecodingError An error while decoding token.
  * @apiErrorExample DecodingError response:
  *     HTTP/1.1 400 Bad Request
  *     {
  *       "error": "An error while decoding token."
  *     }
  */

    /**
     * @api {get} /markers Get All Markers
     * @apiVersion 1.0.0
     * @apiName GetAllMarkers
     * @apiGroup Marker
     *
     * @apiSuccess {Number} id ID of a marker.
     * @apiSuccess {String} title Title (name) of a marker.
     * @apiSuccess {Number} latitude Markers latitude.
     * @apiSuccess {Number} longitude Markers longitude.
     * @apiSuccess {String} type Type of a marker.
     *
     * @apiSuccessExample Success Response:
     *     HTTP/1.1 200 OK
     *     [
     *         {
     *           "id": 1,
     *           "title": "Kultiště",
     *           "latitude": 48.7289231,
     *           "longitude": 16.8966377,
     *           "type": "kultovni_objekt"
     *         },
     *         {
     *           "id": 2,
     *           "title": "Hrob koně",
     *           "latitude": 48.7289903,
     *           "longitude": 16.8965294,
     *           "type": "kultovni_objekt"
     *         }
     *     ]
     */
    public function getAll()
    {
        return response()->json(Marker::all('id', 'title', 'latitude', 'longitude', 'type'));
    }


    /**
     * @api {post} /markers/search Search Markers
     * @apiVersion 1.0.0
     * @apiName SearchMarkers
     * @apiGroup Marker
     *
     * @apiDescription Search for markers in database.
     *
     * @apiHeader {String} Accept application/json
     * @apiHeader {String} Content-Type application/json
     * @apiHeaderExample Search header example
     * Accept: 'application/json',
     * Content-Type: 'application/json'
     *
     * @apiParam {String} query Search query
     *
     * @apiSuccess {Number} id ID of a marker.
     * @apiSuccess {String} title Title (name) of a marker.
     * @apiSuccess {Number} latitude Markers latitude.
     * @apiSuccess {Number} longitude Markers longitude.
     * @apiSuccess {String} type Type of a marker.
     *
     * @apiSuccessExample Success Response:
     *     HTTP/1.1 200 OK
     *     [
     *         {
     *           "id": 1,
     *           "title": "Kultiště",
     *           "latitude": 48.7289231,
     *           "longitude": 16.8966377,
     *           "type": "kultovni_objekt"
     *         },
     *         {
     *           "id": 2,
     *           "title": "Hrob koně",
     *           "latitude": 48.7289903,
     *           "longitude": 16.8965294,
     *           "type": "kultovni_objekt"
     *         }
     *     ]
     *
     */
    public function searchMarkers(Request $request)
    {
        return response()->json(
          Marker::select('id', 'title', 'latitude', 'longitude', 'type')
          ->where('markers.title', 'ilike', '%' .  $request->get('query') . '%')
          ->orWhere(\DB::raw('markers.latitude::text'), 'ilike', '%' .  $request->get('query') . '%')
          ->orWhere(\DB::raw('markers.longitude::text'), 'ilike', '%' .  $request->get('query') . '%')
          ->orWhere(\DB::raw('markers.type::text'), 'ilike', '%' .  $request->get('query') . '%')
          ->orWhere('markers.description', 'ilike', '%' .  $request->get('query') . '%')
          ->orWhere('markers.bibliography', 'ilike', '%' .  $request->get('query') . '%')
          ->get()
        );
    }

   /**
     * @api {get} /markers/:id Get Markers Details
     * @apiVersion 1.0.0
     * @apiName GetMarkerDetails
     * @apiGroup Marker
     *
     * @apiParam {Number} id Markers unique ID.
     *
     * @apiSuccess {Number} id ID of a marker.
     * @apiSuccess {Number} latitude Markers latitude.
     * @apiSuccess {Number} longitude Markers longitude.
     * @apiSuccess {String} type Type of a marker.
     * @apiSuccess {String} title Title (name) of a marker
     * @apiSuccess {String} description Markers description.
     * @apiSuccess {String} bibliography Used bibliography resources.
     * @apiSuccess {Array} photos Array of photos attached to marker.
     *
     * @apiSuccessExample Success Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "id": 8,
     *       "latitude": 48.724896,
     *       "longitude": 16.8958079,
     *       "type": "studna",
     *       "title": "Studna s kamenným vyzděním",
     *       "description": "Studna (objekt 358) měla kruhový půdorys (185 x 210 cm), nálevkovitý tvar. Uvnitř byly nalezeny ploché kameny a části žernovů. Pod nimi začínalo čtvercové kamenné vyzdění studny, které bez přerušení pokračovalo ke dnu.",
     *       "bibliography": "Humlová, B. 2006: Archeologický výzkum raně středověkých studní – metody, analýzy a výstupy. Brno: Masarykova Univerzita. Rukopis bakalárskej diplomovej práce.",
     *       "photos": [
     *         {
     *           "id": 1,
     *           "marker_id": 8,
     *           "src": "Studna_JP_358.jpg",
     *           "thumbnail": "Studna_JP_358.jpg"
     *         }
     *       ]
     *     }
     *
     * @apiError MarkerNotFound Marker with provided id doesn't exists!
     *
     * @apiErrorExample Error Response:
     *     HTTP/1.1 404 Not Found
     *     {
     *       "error": "MarkerNotFound"
     *     }
     */
    public function getMarkerDetails($id)
    {
      $markerDetails = Marker::where('markers.id', $id)->first();

      if (!$markerDetails) {
        return response()->json(["error" => "MarkerNotFound"], 404);
      }

      $photos = Marker::find($id)->photos;

      return response()->json([
          'id' => $markerDetails->id,
          'latitude' => $markerDetails->latitude,
          'longitude' => $markerDetails->longitude,
          'type' => $markerDetails->type,
          'title' => $markerDetails->title,
          'description' => $markerDetails->description,
          'bibliography' => $markerDetails->bibliography,
          'photos' => $photos
        ], 200)->setEncodingOptions(JSON_NUMERIC_CHECK);
    }

   /**
    * @api {post} /markers Create New Marker
    * @apiVersion 1.0.0
    * @apiName CreateNewMarker
    * @apiGroup Marker
    * @apiPermission authenticated
    *
    * @apiUse Header
    *
    * @apiDescription Request params must be sent as <strong>form-data</strong>.
    *
    * @apiParam {String{..50}} title Title (name) of a marker
    * @apiParam {String='kultovni_objekt', 'kostel', 'ropik', 'vyrobni_objekt', 'dum', 'studna'} type Type of a marker.
    * @apiParam {Number} latitude Markers latitude.
    * @apiParam {Number} longitude Markers longitude.
    * @apiParam {String{..254}} description Markers description.
    * @apiParam {String{..254}} bibliography Used bibliography resources.
    *
    * @apiSuccess {Number} id ID of a marker.
    * @apiSuccess {Number} latitude Markers latitude.
    * @apiSuccess {Number} longitude Markers longitude.
    * @apiSuccess {String} type Type of a marker.
    * @apiSuccess {String} title Title (name) of a marker
    * @apiSuccess {String} description Markers description.
    * @apiSuccess {String} bibliography Used bibliography resources.
    *
    * @apiSuccessExample Success Response:
    *     HTTP/1.1 200 OK
    *     {
    *       "id": 8,
    *       "latitude": 48.724896,
    *       "longitude": 16.8958079,
    *       "type": "studna",
    *       "title": "Studna s kamenným vyzděním",
    *       "description": "Studna (objekt 358) měla kruhový půdorys (185 x 210 cm), nálevkovitý tvar. Uvnitř byly nalezeny ploché kameny a části žernovů. Pod nimi začínalo čtvercové kamenné vyzdění studny, které bez přerušení pokračovalo ke dnu.",
    *       "bibliography": "Humlová, B. 2006: Archeologický výzkum raně středověkých studní – metody, analýzy a výstupy. Brno: Masarykova Univerzita. Rukopis bakalárskej diplomovej práce."
    *     }
    *
    * @apiUse JWTErrors
    */
    public function create(Request $request)
    {
      //validate request
      $this->validate($request, [
          'latitude' => 'required|numeric',
          'longitude' => 'required|numeric',
          'type' => 'required|alpha_dash',
          'title' => 'required|max:50',
          'description' => 'max:254',
          'bibliography' => 'max:254'
      ]);

      //create marker
      $marker = Marker::create($request->all());

      return response()->json($marker, 201)->setEncodingOptions(JSON_NUMERIC_CHECK);
    }

    /**
     * @api {delete} /markers/:id Delete Marker
     * @apiVersion 1.0.0
     * @apiName DeleteMarker
     * @apiGroup Marker
     * @apiPermission authenticated
     *
     * @apiUse Header
     *
     * @apiParam {Number} id Markers unique ID.
     *
     * @apiSuccess {String} success Success message.
     *
     * @apiSuccessExample Success Response:
     *     HTTP/1.1 202 OK
     *     {
     *       "success": "Marker was successfully deleted."
     *     }
     *
     * @apiUse JWTErrors
     */
    public function delete($id)
    {
        Marker::findOrFail($id)->delete();
        //delete attached files
        Storage::deleteDirectory('photos/'.$id);

        return response()->json(["success" => "Marker was successfully deleted."], 202);
    }

    /**
     * @api {post} /markers/:id Update Marker
     * @apiVersion 1.0.0
     * @apiName UpdateMarker
     * @apiGroup Marker
     * @apiPermission authenticated
     *
     * @apiUse Header
     *
     * @apiParam {Number} id Markers unique ID.
     *
     * @apiParam {String{..50}} title Title (name) of a marker
     * @apiParam {String='kultovni_objekt', 'kostel', 'ropik', 'vyrobni_objekt', 'dum', 'studna'} type Type of a marker.
     * @apiParam {Number} latitude Markers latitude.
     * @apiParam {Number} longitude Markers longitude.
     * @apiParam {String{..254}} description Markers description.
     * @apiParam {String{..254}} bibliography Used bibliography resources.
     *
     * @apiSuccess {Number} id ID of a marker.
     * @apiSuccess {Number} latitude Markers latitude.
     * @apiSuccess {Number} longitude Markers longitude.
     * @apiSuccess {String} type Type of a marker.
     * @apiSuccess {String} title Title (name) of a marker
     * @apiSuccess {String} description Markers description.
     * @apiSuccess {String} bibliography Used bibliography resources.
     * @apiSuccess {Array} photos Array of photos attached to marker.
     *
     * @apiSuccessExample Success Response:
     *     HTTP/1.1 200 OK
     *     {
     *       "id": 8,
     *       "latitude": 48.724896,
     *       "longitude": 16.8958079,
     *       "type": "studna",
     *       "title": "Studna s kamenným vyzděním",
     *       "description": "Studna (objekt 358) měla kruhový půdorys (185 x 210 cm), nálevkovitý tvar. Uvnitř byly nalezeny ploché kameny a části žernovů. Pod nimi začínalo čtvercové kamenné vyzdění studny, které bez přerušení pokračovalo ke dnu.",
     *       "bibliography": "Humlová, B. 2006: Archeologický výzkum raně středověkých studní – metody, analýzy a výstupy. Brno: Masarykova Univerzita. Rukopis bakalárskej diplomovej práce.",
     *       "photos": [
     *          {
     *           "id": 1,
     *           "marker_id": 8,
     *           "src": "Studna_JP_358.jpg",
     *           "thumbnail": "Studna_JP_358.jpg"
     *         }
     *       ]
     *     }
     *
     * @apiUse JWTErrors
     */
    public function update($id, Request $request)
    {
        $marker = Marker::findOrFail($id);

        $this->validate($request, [
            'latitude' => 'required|numeric',
            'longitude' => 'required|numeric',
            'type' => 'required|alpha_dash',
            'title' => 'required|max:50',
            'description' => 'max:254',
            'bibliography' => 'max:254'
        ]);

        $marker->update($request->all());

        $photos = Marker::find($id)->photos;

        return response()->json([
            'id' => $marker->id,
            'latitude' => $marker->latitude,
            'longitude' => $marker->longitude,
            'type' => $marker->type,
            'title' => $marker->title,
            'description' => $marker->description,
            'bibliography' => $marker->bibliography,
            'photos' => $photos
          ], 200)->setEncodingOptions(JSON_NUMERIC_CHECK);
    }
}
