<?php

namespace App\Services;

use App\Models\Accessory as AccessoryModel;
use Facades\App\Services\PurchaseFileGenerator;

class Accessory
{

    /**
     * Decode the JSON search parameters into an array.
     *
     * @param string $parameters JSON encoded search parameters.
     *
     * @return array Decoded search parameters as an array.
     */
    public function decodeSearch($parameters)
    {
        $search = collect(json_decode($parameters))->toArray();

        $search = array_map(function ($object) {
            return (array) $object;
        }, $search);

        return $search;
    }

    /**
     * Retrieve and return saved search parameters from the request.
     *
     * @return array The saved search parameters.
     */
    public function getSavedSearchParameters()
    {
        $parameters = [];

        if (request('locations')) {
            $parameters['location'] = request('locations');
        }

        if (request('make_and_model')) {
            $parameters['make_and_model'] = request('make_and_model');
        }

        if (request('purchase_indicator')) {
            $parameters['purchase_indicator'] = request('purchase_indicator');
        }

        return $parameters;
    }

    /**
     * Retrieve and return filtered accessories data.
     *
     * @return array The accessories data including count, purchase indicator, and purchase file.
     */
    public function getAccessoriesData()
    {
        $purchaseFile = '';
        $accessories = AccessoryModel::with(['location', 'makeAndModel.manufacturer', 'technicalSpec']);
        $inputData = $this->getInputData(request('form'));
        $accessories = $this->filter($accessories, $inputData);

        $count = $accessories->count('accessories.id');

        $accessories = $this->getOutputData($accessories);

        $purchaseIndicator = $inputData['purchaseIndicator'];

        if ($purchaseIndicator) {
            $purchaseFile = PurchaseFileGenerator::create($accessories);
        }

        return compact('accessories', 'count', 'purchaseIndicator', 'purchaseFile');
    }

    /**
     * Extract input data from the form.
     *
     * @param array $form The form data.
     *
     * @return array The extracted input data.
     */
    private function getInputData($form)
    {
        return [
            'makeAndModel'      => isset($form['make_and_model']) ? $form['make_and_model'] : '',
            'location'          => isset($form['location']) ? $form['location'] : '',
            'purchaseIndicator' => isset($form['purchase_indicator']) ? $form['purchase_indicator'] : '',
        ];
    }

    /**
     * Apply filters to the accessories query based on input data.
     *
     * @param Builder $accessories The accessories query builder.
     * @param array   $inputData   The input data for filtering.
     *
     * @return Builder The filtered accessories query builder.
     */
    public function filter($accessories, $inputData)
    {
        if ($inputData['makeAndModel']) {
            if (is_array($inputData['makeAndModel'])) {
                $accessories = $accessories->whereIn('make_and_model_id', $inputData['makeAndModel']);
            } else {
                $accessories = $accessories->where('make_and_model_id', $inputData['makeAndModel']);
            }
        }

        if ($inputData['location']) {
            if (is_array($inputData['location'])) {
                $accessories = $accessories->whereIn('location_id', $inputData['location']);
            } else {
                $accessories = $accessories->where('location_id', $inputData['location']);
            }
        }

        if ($inputData['purchaseIndicator'] != '') {
            if (is_array($inputData['purchaseIndicator'])) {
                $accessories = $accessories->whereIn('purchase_indicator', $inputData['purchaseIndicator']);
            } else {
                $accessories = $accessories->where('purchase_indicator', $inputData['purchaseIndicator']);
            }
        }

        return $accessories;
    }

    /**
     * Get the output data for the accessories query with pagination and ordering.
     *
     * @param Builder $accessories The accessories query builder.
     *
     * @return \Illuminate\Database\Eloquent\Collection The result of the query.
     */
    public function getOutputData($accessories)
    {
        $start = request('start');
        $limit = request('length');

        if ($limit != -1) {
            $accessories = $accessories->offset($start)
                ->limit($limit);
        }

        $accessories = $accessories->orderBy('id', 'desc');

        return $accessories->get();
    }

    /**
     * Process and return the data for each accessory.
     *
     * @param \Illuminate\Database\Eloquent\Collection $accessories The collection of accessories.
     * @param int                                      $start       The starting index for the data.
     * @param array                                    $data        The initial data array to be filled.
     *
     * @return array The processed data array.
     */
    public function getData($accessories, $start, $data)
    {
        $parentIndex = $start;

        foreach ($accessories as $accessory) {
            $parentIndex++;

            $nestedData = $this->getNestedData($accessory, $parentIndex, '', '');

            $data[] = $nestedData;
        }

        return $data;
    }

    /**
     * Get the nested data for an accessory.
     *
     * @param AccessoryModel $accessory The accessory data.
     * @param int            $index     The index for the accessory.
     * @param string         $last      The last data string.
     * @param string         $parent    The parent data string.
     *
     * @return array The nested data.
     */
    public function getNestedData($accessory, $index, $last, $parent)
    {
        $nestedData['dataLast'] = $last;
        $nestedData['dataId'] = $accessory->id;
        $nestedData['dataParent'] = $parent;

        $nestedData['id'] = $index;

        $id = $accessory->id;
        $makeAndModel = (optional($accessory->makeAndModel)->makeModelName ?? '');
        $deleteUrl = route('accessories.destroy', $id);
        $updateUrl = route('accessories.update', ['accessory' => $id]);

        if ($accessory->available_quantity == 0) {
            $nestedData['action_one'] = " ";
            $nestedData['action_two'] = "<form id='" . $accessory->id . "' action='" . $deleteUrl . "' method='POST'><input type='hidden' name='_method' value='DELETE'><input type='hidden' name='_token' value='" . csrf_token() . "'><input type='button' colspan='2' id='btndelete' value='Delete' class='btndelete btn btn-block btn-danger btn-sm' ><input type='hidden' id='hardware_standard' value='" . $makeAndModel . "'>
            </form>";
            $nestedData['action_three'] = "<a href='' data-action='" . $updateUrl . "' class='btn btn-primary btn-sm'  data-toggle='modal' data-post-id='" . $id . "' data-target='#addModal'>Add</a>";
        }

        if ($accessory->available_quantity != 0) {
            $nestedData['action_one'] = "<a href='' data-action='" . $updateUrl . "'  class='btn btn-primary btn-sm accessoriesModal' data-post-id='" . $id . "' data-post-quantity='" . $accessory->available_quantity . "' data-toggle='modal' data-target='#moveModal'>Transfer</a>";

            $nestedData['action_two'] = "<a href='' data-action='" . $updateUrl . "' class='btn btn-primary btn-sm'  data-toggle='modal' data-post-id='" . $id . "' data-post-quantity='" . $accessory->available_quantity . "' data-target='#useModal'>Consume</a>";

            $nestedData['action_three'] = "<a href='' data-action='" . $updateUrl . "' class='btn btn-primary btn-sm'  data-toggle='modal' data-post-id='" . $id . "' data-target='#addModal'>Add</a>";
        }

        $nestedData['location'] = $accessory->location->room_name ?? '';
        $nestedData['hardware_standard'] = $makeAndModel;
        $nestedData['available_quantity'] = $accessory->available_quantity;



        $nestedData['weekly_demand'] = "<input style='width:100%' onblur='updateQuantity(\"weekly_demand\", $id, this)' type='number' min='0' oninput='validity.valid||(value=\"\");' class='form-control' value='" . $accessory->weekly_demand . "'>";

        $nestedData['lead_time'] = "<input style='width:100%' onblur='updateQuantity(\"lead_time\", $id, this)' type='number' min='0' oninput='validity.valid||(value=\"\");' class='form-control' value='" . $accessory->lead_time . "'>";

        $nestedData['order_quantity'] = "<span id='order-qty-$id'>" . $accessory->order_quantity . "</span>";
        $indicator = $accessory->purchase_indicator ? 'Yes' : 'No';
        $nestedData['purchase_indicator'] = "<span id='purchase-indicator-$id'>" . $indicator . "</span>";

        return $nestedData;
    }
}
