<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Recipe;
use App\RecipeIngredient;
use App\RecipeCategory;
use App\User;

class RecipeController extends Controller
{
  public function index()
  {
    $recipes = Recipe::with('user')->get();
    $categories=array_values(RecipeCategory::get()->sortby('name')->pluck('name')->unique()->toArray());
    return view('recipes.index')->with('recipes', $recipes)->with('categories',$categories);
  }

  public function show($id)
  {
    $recipe=Recipe::with('user')->findOrFail($id);
    return view('recipes.show')->with('recipe', $recipe);
  }

  public function edit($id){
    $recipe=Recipe::with('user')->with('categories')->with('ingredients')->findOrFail($id);
    $lists['ingredients']=array_values(RecipeIngredient::get()->sortby('name')->pluck('name')->unique()->toArray());
    $lists['measurements']=array_values(RecipeIngredient::get()->sortby('measurement')->pluck('measurement')->unique()->toArray());
    $lists['categories']=array_values(RecipeCategory::get()->sortby('name')->pluck('name')->unique()->toArray());
    $lists['authors']=array_values(Recipe::get()->sortby('author')->pluck('author')->unique()->toArray());
    $lists['owners']=User::select('id','name')->get()->sortby('name');
    return view('recipes.edit')->with('recipe', $recipe)->with('lists',$lists);
  }

  public function update(Request $request, $id)
  {
    $recipe = Recipe::with('ingredients')->with('categories')->findOrFail($id);

    $this->validate($request, [
      'author'=>'required|max:500',
      'user_id'=>'required',
      'servings'=>'required|integer',
      'serving_size'=>'required|max:40',
      'description'=>'max:5000',
      'instructions'=>'required|max:5000'
    ]);

    //break categories and ingredients into arrays for validation
    $categories = array();
    $ingredients = array();
    foreach($request->all() as $element => $value){
      if(preg_match('/category_.*/', $element)){
        $explosion = explode('_',$element);
        $categories[$explosion[1]][$explosion[2]]=$value;
      }else if(preg_match('/ingredient_.*/', $element)){
        $explosion = explode('_',$element);
        $ingredients[$explosion[1]][$explosion[2]]=$value;
      }
    }

    foreach($categories as $category){
      $newreq = new Request($category);
      $this->validate($newreq, [
        'name'=>'required|max:50',
      ]);
    }

    foreach($ingredients as $index => $ingredient){
      $newreq = new Request($ingredient);
      $this->validate($newreq, [
        'order'=>'required|integer',
        'quantity'=>['required','regex:/(^\d+\/\d+$)|(^\d*\.\d+$)|(^\d+ \d\/\d$)|(^\d+$)/i'],
        'measurement'=>'required|max:40',
        'name'=>'required|max:500',
        'notes'=>'max:500'
      ]);
      if ($ingredient['notes'] == null){
        $ingredients[$index]['special_notes'] = '';
      }else{
        $ingredients[$index]['special_notes'] = $ingredient['notes'];
      }
      if(array_key_exists('alternative', $ingredient) && $ingredient['alternative'] == 'on'){
        $ingredients[$index]['alternative'] = true;
      }else{
        $ingredients[$index]['alternative'] = false;
      }
    }

    $update = $request->only('author','user_id','servings','serving_size','description','instructions');
    $recipe->fill($update)->save();

    //Delete categories that don't exist in new category array
    foreach($recipe->categories as $category){
      if(!array_key_exists($category->id,$categories)){
        $category->delete();
      }
    }

    //Delete ingredients that don't exist in new ingredient array
    foreach($recipe->ingredients as $ingredient){
      if(!array_key_exists($ingredient->id,$ingredients)){
        $ingredient->delete();
      }
    }

    //create/update categories
    foreach($categories as $categoryid => $category){
      //Add recipe_id
      $category["recipe_id"]=$id;
      $newreq = new Request($category);
      //Find category if exists, create if it doesn't
      $currentcategory = RecipeCategory::where('id','=',$categoryid)->first();
      if($currentcategory === null){
        RecipeCategory::create($newreq->only('recipe_id','name'));
      }else{
        $update = $newreq->only('recipe_id','name');
        $currentcategory->fill($update)->save();
      }
    }

    //create/update ingredients
    foreach($ingredients as $ingredientid => $ingredient){
      //Add recipe_id
      $ingredient["recipe_id"]=$id;
      $newreq = new Request($ingredient);
      //Find category if exists, create if it doesn't
      $currentingredient = RecipeIngredient::where('id','=',$ingredientid)->first();
      if($currentingredient === null){
        RecipeIngredient::create($newreq->only('recipe_id','order','alternative','quantity','measurement','name','special_notes'));
      }else{
        $update = $newreq->only('recipe_id','order','alternative','quantity','measurement','name','special_notes');
        $currentingredient->fill($update)->save();
      }
    }
    return redirect()->route('recipes.index')->with('message','Recipe successfully edited.');
  }
}
