<?php

namespace App\Http\Controllers\Admin;

use App\Models\AttributeChoice;
use App\Models\ChoiceAttribute;
use App\Models\ChoiceDescription;
use Exception;
use App\Models\Attribute;
use App\Models\Choice;
use Illuminate\View\View;
use App\Models\AttributeDescription;
use Illuminate\Http\Request;
use App\Services\Response\ResponseService;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Redirector;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\AttributeRequest;
use Illuminate\Http\RedirectResponse;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;

class AttributeController extends Controller
{

    /** Redirect to this path after each operation success*/
    private $redirectSuccessPath= '/admin/attributes';
    /** View folder */
    private $viewDirectory= 'admin.attributes.';
    private $viewAjax= 'admin.ajax.';

    /**
     * Display a listing of the resource.
     *
     * @param Request $request
     * @return View
     */
    public function index(Request $request) :View
    {
        $title= __('attributes.head');
        $request= $request->toArray();
        return view($this->viewDirectory.'index',compact('title'));
    }

    /**
     * return data of the pages.
     *
     * @param Request $request
     * @return View
     */
    public function grid(Request $request) :View
    {
        $query = Attribute::latest()
            ->join('attribute_descriptions AS ad', 'attributes.id', 'ad.attribute_id')
            ->join('languages', 'languages.id', 'ad.language_id')
            ->where('local', LaravelLocalization::getCurrentLocale())
            ->select(['ad.*', 'attributes.*']);

        if ($request->date_from) {
            $query->whereDate('attributes.created_at', '>=', $request->date_from);
        }

        if ($request->date_to) {
            $query->whereDate('attributes.created_at', '<=', $request->date_to);
        }

        if ($request->title) {
            $query->where('ad.name', 'LIKE', '%'.$request->title.'%');
        }
        if ($request->type) {
            $query->where('attributes.status', $request->type);
        }

        if ($request->description) {
            $query->where('ad.description', 'LIKE', '%'.$request->description.'%');
        }
        if ($request->link) {
            $query->where('link', 'LIKE', '%'.$request->link.'%');
        }
        if ( !is_null($request->status) && $request->status == 0) {
            $query->onlyTrashed();
        }

        $attributes= $query->paginate(100);

        return view($this->viewDirectory.'grid',compact('attributes'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return View
     */
    public function create() :View
    {
        $action= route('attributes.store');
        $head= __('attributes.new');
        $attributes = Attribute::withDescription()->where('attributes.type','main')->where('attributes.status','multi')->cursor();
        return view( $this->viewDirectory.'form', compact('action', 'head','attributes') );
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param AttributeRequest $request
     * @return RedirectResponse|Redirector
     */
    public function store(AttributeRequest $request) 
    {
        if($request->status == 'one')
        {
            $request->merge(['type'=>'main']);
        }
        $attribute = Attribute::create($request->all());

        // Insert Description
        $this->saveData($request, $attribute->id);


        session()->flash('message', __('dashboard.saveDone'));
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> $this->redirectSuccessPath,
        ];
        return ResponseService::response($response);
    }


    /**
     * Show the form for editing the specified resource.
     *
     * @param Attribute $attribute
     * @return View
     */
    public function edit(Attribute $attribute) :View
    {
        $action= route('attributes.update', $attribute->id);

        $head= __('attributes.edit');

        $query = AttributeDescription::where('attribute_id', $attribute->id)
            ->join('languages', 'languages.id', 'attribute_descriptions.language_id')
            ->select(['attribute_descriptions.*', 'languages.local']);

        $attributeDescription= $query->get();
        foreach ($attributeDescription as $row) {
            $attribute[$row->local]= $row;
        }
        $choices = Choice::cursor();
        $attr_choices = AttributeChoice::where('attribute_id',$attribute->id)->cursor();

        return view( $this->viewDirectory.'form', compact('attribute','head','action','choices','attr_choices') );
    }

    /**
     * Update the specified resource in storage.
     *
     * @param AttributeRequest $request
     * @param Attribute $attribute
     * @return RedirectResponse|Redirector
     */
    public function update(AttributeRequest $request, Attribute $attribute) 
    {
        // Update image and category id if request has it

        if($request->status == 'one')
        {
            $request->merge(['type'=>'main']);
        }

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

        // Delete old description
        AttributeDescription::where('attribute_id', $attribute->id)->delete();
        AttributeChoice::where('attribute_id', $attribute->id)->delete();
        ChoiceAttribute::where('attribute_id', $attribute->id)->delete();

        // Insert new description
        $this->saveData( $request, $attribute->id );

        session()->flash('message', __('dashboard.saveDone'));
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> $this->redirectSuccessPath,
        ];
        return ResponseService::response($response);
    }

    /**
     * Handle Save form data
     *
     * @param AttributeRequest $request
     * @param int $attribute_id
     * @return void
     */

    private function saveData(AttributeRequest $request, int $attribute_id ):void
    {

        $requestData= $request->all();
        foreach (languages() as $lang) {
            $data=[
                'attribute_id'=> $attribute_id,
                'language_id'=> $lang->id,
                'name'=> $requestData['name_'.$lang->local],
            ];
            AttributeDescription::create($data);
        }
        if (isset($request->choices))
        {
            foreach ($request->choices as $row)
            {
                $data=[
                    'choice_id'=> $row['id'],
                    'attribute_id'=> $attribute_id,
                ];
                AttributeChoice::create($data);

            }
        }
//        if($request->status == 'multi')
//        {
//            if($request->type == 'sub')
//            {
//                ChoiceAttribute::create([
//                    'attribute_choice_id' => $request->choice_id,
//                    'attribute_id' => $attribute_id,
//                ]);
//            }
//        }

    }

    public function choices(Request $request)
    {
        $choices = AttributeChoice::where('attribute_id',$request->attribute_id)->cursor();
        return view( $this->viewAjax.'attr_choices', compact('choices') );
    }

    public function addChoice(Request $request)
    {
        $key = $request->key;
        $choices = Choice::cursor();
        return view( $this->viewAjax.'choices', compact('key','choices') );
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws Exception
     */
    public function destroy(Request $request, int $id) :JsonResponse
    {
        $attribute = Attribute::withTrashed()->find($id);
        if ($attribute) {
            if ($attribute->deleted_at) {
                $attribute->forceDelete();
            } else {
                $attribute->delete();
            }
            return response()->json(['message'=> __('dashboard.deletedDone')]);
        } else{
            return response()->json(['message'=> __('dashboard.noResult')], 400);
        }
    }

    /**
     * Remove several pages by IDs.
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function destroyAll(Request $request) :JsonResponse
    {
        $ids= $request->ids;
        if ($request->force) {
            Attribute::onlyTrashed()->whereIn('id', $ids)->forceDelete();
        } else {
            Attribute::whereIn('id', $ids)->delete();
        }

        return response()->json(['message'=> __('dashboard.deletedDone')]);
    }

    /**
     * Restore the specified category from storage
     *
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     */
    public function restore(Request $request, int $id) :JsonResponse
    {
        $attribute = Attribute::withTrashed()->find($id);

        if ($attribute){
            $attribute->restore();
            return response()->json(['message'=> __('dashboard.saveDone')]);
        }
        return response()->json(['message'=> __('dashboard.noResult')], 400);
    }

    /**
     * Restore several pages by IDs.
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function restoreAll(Request $request) :JsonResponse
    {
        $attribute = Attribute::whereIn('id', $request->ids)->onlyTrashed();
        if ($attribute){
            $attribute->restore();
            return response()->json(['message'=> __('dashboard.saveDone')]);
        }
        return response()->json(['message'=> __('dashboard.saveDone')]);
    }
}
