<?php

namespace App\Services\Integrations\Asn;

use App\Models\AsnAccessoriesMapping;
use App\Models\AsnUnwantedPart;
use App\Models\Asset;
use App\Models\AssetTracking;
use App\Models\MakeAndModel;
use Illuminate\Support\Facades\Validator;

abstract class AbstractAsnImportService
{
    abstract protected function CreateAsnData($item, $count = null);
    abstract protected function setAssetArray($item);
    abstract protected function createAssetHistory($asset);

    public function __construct()
    {
    }

    /**
     * updateTrackingNumber
     *
     * @param  mixed $item
     * @return void
     */
    public function updateTrackingNumber($item, $trackingNumber, $serialNumber)
    {
        $trackingNumber = $item[$trackingNumber] ?? '';
        $serial_no      = $item[$serialNumber] ?? '';
        $asset_tag      = isset($item['Asset Tag']) ? $item['Asset Tag'] : '';

        if (!$trackingNumber || !($serial_no || $asset_tag)) {
            return;
        }

        $asset = new Asset;
        if ($serial_no) {
            $asset = $asset->where('serial_no', stripS($serial_no));
        }
        if ($asset_tag) {
            $asset = $asset->where('asset_tag', stripS($asset_tag));
        }
        $asset = $asset->first();

        if (!$asset) {
            return;
        }

        $tracking = AssetTracking::firstOrCreate(['tracking_number' => $trackingNumber]);
        $asset->update(['asset_tracking_id' => $tracking->id]);

        return true;
    }


    /**
     * Check the item is accessory or not
     * @param mixed $item
     * @param mixed $provider
     * @param null $manufacturerPart
     * 
     * @return bool
     */
    public function isAccessories($item, $provider = 'asn', $manufacturerPart = null)
    {
        if (isset($item[$manufacturerPart])) {
            $accessories = AsnAccessoriesMapping::where(['provider' => $provider, 'part_no' => trim($item[$manufacturerPart])])->first();
            return $accessories ? true : false;
        }

        return false;
    }

    /**
     * Check the item is Unwanted part or not based on the Mapping
     * @param mixed $manufacturerPart
     * @param string $provider
     * 
     * @return bool
     */
    public function isUnwantedPart($manufacturerPart = null, $provider = 'asn')
    {
        if (isset($manufacturerPart)) {
            $isUnwantedPart = AsnUnwantedPart::where(['provider' => $provider, 'part_no' => trim($manufacturerPart)])->first();
            return $isUnwantedPart ? true : false;
        }

        return false;
    }

    /**
     * isServicese
     *
     * @param  mixed $itemType
     * @return void
     */
    public function isServicese($itemType)
    {
        if (strpos(strtolower($itemType), 'services') !== false) {
            return true;
        }

        return false;
    }

    /**
     * getTechDetails
     * @param mixed $item
     * @param mixed $hardware
     * @param null $manufacturerPart
     * 
     * @return $assetData
     */
    public function getTechDetails($item, $hardware = null)
    {
        $assetData['make_and_model_id'] = '';
        $assetData['technical_spec_id'] = '';
        $assetData['asset_type_id'] = '';

        if (!empty($hardware)) {
            $makeAndModel = MakeAndModel::find($hardware->make_and_model_id);
            $assetData['make_and_model_id'] = $hardware->make_and_model_id;
            $assetData['technical_spec_id'] = $hardware->technical_spec_id;
            $assetData['asset_type_id']     = $makeAndModel->asset_type_id;
        }

        return $assetData;
    }


    function checkIfAsnDataValid($asnData, $key)
    {
        if (!empty($asnData['error'])) {
            return $asnData['error'];
        }
        return $this->validateItem($asnData['assetData'], $key);
    }

    /**
     * validateItem
     *
     * @param  mixed $asnData
     * @return void
     */
    public function validateItem($asnData, $count = null)
    {
        $validationError = [];
        if (empty($asnData)) {
            $validationError['asndata'] = ['Line No ' . $count . ': No ASN Data Found'];
            return $validationError;
        }

        $validator = Validator::make(
            $asnData,
            [
                'po_id' => 'required|alpha_dash',
                'serial_no' => 'required|unique:assets,serial_no|alpha_dash',
                // 'asset_tag' => 'unique:assets,asset_tag|alpha_dash',
                // 'ticket_no' => 'required|alpha_dash',
                'asset_status_id' => 'required|integer',
                'part_no' => 'required',
            ],
            $messages = [
                'po_id.required' => 'Line no ' . $count . ' : The PO ID is required.',
                'po_id.alpha_dash' => 'Line no ' . $count . ' : The PO ID contains disallowed characters / invalid.',
                'serial_no.required' => 'Line no ' . $count . ' : The serial # is required.',
                'serial_no.unique' => 'Line no ' . $count . ' : The serial # already exists',
                'serial_no.alpha_dash' => 'Line no ' . $count . ' : The serial # contains disallowed characters / invalid.',
                // 'asset_tag.required' => 'Line no ' . $count . ' : The asset tag # is required.',
                // 'asset_tag.alpha_dash' => 'Line no ' . $count . ' : The asset tag # contains disallowed characters / invalid.',
                // 'asset_tag.unique' => 'Line no ' . $count . ' : The asset tag # already exists',
                // 'ticket_no.alpha_dash' => 'Line no ' . $count . ' : The ticket # contains disallowed characters / invalid.',
                // 'ticket_no.required' => 'Line no ' . $count . ' : The ticket # is required.',
                'asset_status_id.required' => 'Line no ' . $count . ' : The asset status is required.',
                'part_no.required' => 'Line no ' . $count . ' : Please add manufacturer part.',
            ]
        );

        if ($validator->fails()) {
            return $validator->errors()->toArray();
        }
    }
}
