<?php

namespace App\Core\Service;


use App\Core\Repository\Product\ProductRepository;
use App\Core\Service\PropertyProductMappingService;
use App\Core\Service\ProductParameterMappingService;


use App;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;
use Exception;
use App\Exceptions\ApiErrorException;

class ProductService
{

    private $productRepository;
    private $propertyProductMappingService;
    private $productParameterMappingService;

    public function __construct(
        ProductRepository              $productRepository,
        PropertyProductMappingService  $propertyProductMappingService,
        ProductParameterMappingService $productParameterMappingService
    )
    {
        $this->productRepository = $productRepository;
        $this->propertyProductMappingService = $propertyProductMappingService;
        $this->productParameterMappingService = $productParameterMappingService;
    }

    public function select($param = [], $column = ['*'])
    {

        $response = ['status' => -1, 'message' => '', 'data' => null];

        try {

            $data = $this->productRepository->findByCriteria($param, $column);
            $response = [
                'status' => true,
                'data' => $data,
            ];

        } catch (ApiErrorException $e) {
            $response['message'] = $e->getMessage();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        return output($response);
    }

    public function getPropertyProducts($params = [])
    {

        $response = ['status' => -1, 'message' => '', 'data' => null];

        try {

            $productCriteria = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'with' => []
            ];

            $products = $this->select($productCriteria);


            if ($products['status'] != 'success') {
                throw new ApiErrorException(lang('Fact data not loaded'));
            }

            $productsCollection = collect($products['data']);

            $propertyProductMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ]
            ];

            $propertyProductMappingData = $this->propertyProductMappingService->select($propertyProductMappingCriteria);
            if ($propertyProductMappingData['status'] != 'success') {
                throw new ApiErrorException(lang('Property Product data not loaded'));
            }

            $propertyProductMappingData = $propertyProductMappingData['data'] ? $propertyProductMappingData['data'] : [];

            $propertyProductMappingDataCollection = collect($propertyProductMappingData);

            $productParameterMappingCriteria = [
                'criteria' => [
                    ['field' => 'property_id', 'condition' => '=', 'value' => $params['property_id']],
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'with' => ['parameterDetail']
            ];

            $productParameterMappingData = $this->productParameterMappingService->select($productParameterMappingCriteria);
            $productParameterMappingDataCollection = collect($productParameterMappingData['data'] ?? []);

            $propertyProducts = [];
            foreach ($products['data'] as $product) {

                $productParameterArray = null;
                $productMappingDetail = $propertyProductMappingDataCollection->where('product_id', $product['id'])->first();
                if (isset($productMappingDetail['parameterArray']) && !empty($productMappingDetail['parameterArray'])) {
                    $productParameterArray = $productMappingDetail['parameterArray'];
                }

                $propertyProducts[$product['id']] = $product;
                $propertyProducts[$product['id']]['property_has_product'] = count($propertyProductMappingDataCollection->where('product_id', $product['id'])->toArray()) ? true : false;
                $propertyProducts[$product['id']]['parameterArray'] = $productParameterArray;
                $propertyProducts[$product['id']]['parameters'] = $productParameterMappingDataCollection
                    ->where('product_id', $product['id'])
                    ->values()
                    ->map(function ($item) {
                        return [
                            'product_parameter_id' => $item['product_parameter_id'] ?? null,
                            'is_selected' => $item['is_selected'] ?? null,
                            'value' => $item['value'] ?? null,
                            'unit' => $item['unit'] ?? null,
                            'parameter_detail' => isset($item['parameterDetail']) ? [
                                'id' => $item['parameterDetail']['id'] ?? null,
                                'name' => $item['parameterDetail']['name'] ?? null,
                            ] : (isset($item['parameter_detail']) ? [
                                'id' => $item['parameter_detail']['id'] ?? null,
                                'name' => $item['parameter_detail']['name'] ?? null,
                            ] : null)
                        ];
                    })->all();
            }

            $response = [
                'status' => true,
                'data' => $propertyProducts,
            ];

        } catch (ApiErrorException $e) {
            $response['message'] = $e->getMessage();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        return output($response);
    }

    public function setDefaultPropertyProducts($params = [])
    {

        $response = ['status' => -1, 'message' => '', 'data' => null];

        try {

            $productCriteria = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                ],
                'whereIn' => [
                    ['field' => 'id', 'value' => [1, 4, 5]]
                    //['field' => 'id', 'value' => [1, 2, 3, 4, 5, 6]]
                ],
                'with' => []
            ];

            $products = $this->select($productCriteria);
            if ($products['status'] != 'success') {
                throw new ApiErrorException(lang('Products data not loaded'));
            }


            $createParam['property_id'] = fillOnUndefined($params, 'property_id');
            foreach ($products['data'] as $product) {
                $createParam['products'][] = [
                    'product_id' => fillOnUndefined($product, 'id')
                ];

            }

            $setProducts = $this->propertyProductMappingService->create($createParam);
            if ($setProducts['status'] != 'success') {
                throw new ApiErrorException($setProducts['message']);
            }

            $response = [
                'status' => true,
                'data' => $products['data'],
            ];

        } catch (ApiErrorException $e) {
            $response['message'] = $e->getMessage();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }

        return output($response);
    }

    public function propertyProductActivate($params = [])
    {

        $response = ['status' => -1, 'message' => '', 'data' => null];

        try {

            $productCriteria = [
                'criteria' => [
                    ['field' => 'status', 'condition' => '=', 'value' => 1],
                    ['field' => 'id', 'condition' => '=', 'value' => $params['product_id']],
                ],
                'firstRow' => true
            ];

            $productCheck = $this->select($productCriteria);
            if ($productCheck['status'] != 'success') {
                throw new ApiErrorException(lang('Products data not loaded'));
            }


            $createParam['property_id'] = fillOnUndefined($params, 'property_id');

            $createParam['products'][] = [
                'product_id' => fillOnUndefined($params, 'product_id'),
                'expiration_date' => Carbon::now()->addMonth()->toDateString(),
                'amount' => fillOnUndefined($params, 'amount'),
                'currency' => fillOnUndefined($params, 'currency'),
            ];

            $setProducts = $this->propertyProductMappingService->create($createParam);
            if ($setProducts['status'] != 'success') {
                throw new ApiErrorException($setProducts['message']);
            }

            $response = [
                'status' => true,
                'data' => $setProducts['data'],
            ];

        } catch (ApiErrorException $e) {
            $response['message'] = $e->getMessage();
        } catch (Exception $e) {
            $message = $e->getFile() . " " . $e->getLine() . " " . $e->getMessage();
            Log::error($message);
            $response['message'] = $e->getMessage();
        }


        return output($response);
    }

}
