<?php

namespace App\Http\Controllers;

use App\BoxProduct;
use App\Repositories\BoxProductRepository;
use App\Repositories\BoxRepository;
use App\Repositories\CompanyRepository;
use Illuminate\Http\Request;

class BoxProductController extends Controller
{

    public function __construct() {
        $this->middleware('auth:api',['except' => []]);
    }

    /**
     * @param Request $request
     * @return Array de BoxProduct
     *
     * SI ERES SUPERADMIN:
     *      - Pots passar company_id o box_id, i filtrar
     *      - O bé pots veure'ls tots
     * SI ERES COMPANY ADMIN:
     *      - Has de passar si o si company_id o box_id
     *      - Sense company_id o box_id no fas res
     * SI ERES BOX ADMIN:
     *      - Igual que company admin pero amb el box_id sol
     * ALTRES:
     *      -
     */
        public function index(Request $request) {
        //1. Query params
        $company_id = $request->query("company_id");
        $box_id = $request->query("box_id");

        //2. Authorize
        try {
            $products = null;
            if($company_id) {
                auth()->user()->authorize("view-company-box-products", $company_id);
                $products = CompanyRepository::findOrFail($company_id)->box_products;
            }
            elseif($box_id) {
                auth()->user()->authorize("view-box-box-products", null, $box_id);
                $products = BoxRepository::findOrFail($box_id)->boxProducts;
            }
            else {
                auth()->user()->authorize("view-all-box-products");
                $products = BoxProductRepository::all();
            }
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($products, 200);
    }

    public function show($id) {
        try {
            //1. Query params
            $box_id = BoxProductRepository::findOrFail($id)->box_id;
            $company_id = BoxRepository::company($box_id)->id;

            //2. Autoritzar
            if($company_id) auth()->user()->authorize(["view-all-box-products", "view-company-box-products", "view-box-box-products"], $company_id);
            elseif($box_id) auth()->user()->authorize(["view-all-box-products", "view-company-box-products", "view-box-box-products"], null, $box_id);
            else auth()->user()->authorize(["view-all-box-products"]);

            //3. Retrieve
            $product = BoxProductRepository::find($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($product, 200);
    }

    public function create(Request $request) {
        try {
            //1. Query params
            $box_id = $request->box_id;
            $company_id = BoxRepository::company($box_id)->id;

            //2. Authorize - NO POSAR ELS ID AQUI!
            auth()->user()->authorize("create-box-products");

            //3. Retrieve
            $product = BoxProductRepository::create($request->all());

        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($product, 200);
    }

    public function update(Request $request, $id) {
        try {
            //1. Query params
            $box_id_origin = $request->box_id;
            $box_id_dest = BoxProductRepository::findOrFail($id)->box_id;
            $company_id_origin = BoxRepository::company($box_id_origin)->id;
            $company_id_dest = BoxRepository::company($box_id_dest)->id;

            //2. Autoritzem - NO POSAR ELS ID AQUI!


            //3. Retrieve i capar
            $product = BoxProductRepository::update($request->all(), $id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($product, 200);
    }

    public function destroy($id) {
        try {
            //1. Query params

            //2. Authorize

            //3. Retrieve
            BoxProductRepository::delete($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json(["message" => "Ok"], 200);
    }

    /**************************************************************************************
     **************************************************************************************
     *                              BOX PRODUCT VARIANTS
     **************************************************************************************
     *************************************************************************************/
    public function indexVariant($product_id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::findOrFail($product_id)->id;

            //2. Check & Authorize

            //3. Execute
            $res = BoxProductRepository::allVariant($product_id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function createVariant(Request $request, $product_id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::findOrFail($product_id)->id;

            //2. Check & Authorize

            //3. Execute
            $res = BoxProductRepository::createVariant($product_id, $request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function showVariant($product_id, $id) {
        try {
            //1. Params

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $id);

            //3. Execute
            $res = BoxProductRepository::findVariant($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function updateVariant(Request $request, $product_id, $id) {
        try {
            //1. Params

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $id);

            //3. Execute
            $res = BoxProductRepository::updateVariant($id, $request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function destroyVariant($product_id, $id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::find($product_id)->id;

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $id);

            //3. Execute
            $res = BoxProductRepository::deleteVariant($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    private function checkProductVariantConsistence($product_id, $variant_id) {
        abort_unless(
            BoxProductRepository::findVariant($variant_id)->box_product_id == $product_id,
            401,
            "La variante de producto no es del producto especificado"
        );
    }


    /**************************************************************************************
     **************************************************************************************
     *                              BOX PRODUCT IMAGES
     **************************************************************************************
     *************************************************************************************/
    public function indexImage($product_id, $variant_id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::find($product_id)->id;

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $variant_id);

            //3. Execute
            $res = BoxProductRepository::allImage($variant_id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function createImage(Request $request, $product_id, $variant_id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::find($product_id)->id;

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $variant_id);

            //3. Execute
            $res = BoxProductRepository::createImage($variant_id, $request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function showImage($product_id, $variant_id, $id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::find($product_id)->id;

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $variant_id);
            $this->checkVariantImageConsistence($variant_id, $id);

            //3. Execute
            $res = BoxProductRepository::findImage($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function updateImage(Request $request, $product_id, $variant_id, $id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::find($product_id)->id;

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $variant_id);
            $this->checkVariantImageConsistence($variant_id, $id);

            //3. Execute
            $res = BoxProductRepository::updateImage($id, $request->all());
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    public function destroyImage($product_id, $variant_id, $id) {
        try {
            //1. Params
            $box_id = BoxProductRepository::find($product_id)->id;

            //2. Check & Authorize
            $this->checkProductVariantConsistence($product_id, $variant_id);
            $this->checkVariantImageConsistence($variant_id, $id);

            //3. Execute
            $res = BoxProductRepository::deleteImage($id);
        }
        catch(\Exception $e) { return response()->json(["error" => $e->getMessage()], 400); };

        return response()->json($res);
    }

    private function checkVariantImageConsistence($variant_id, $image_id) {
        abort_unless(
            BoxProductRepository::findImage($image_id)->box_product_variant_id == $variant_id,
            401,
            "La imagen de producto no es del producto especificado"
        );
    }


}

