<?php

namespace App\Services\Settings;

use App\Http\Traits\BulkUploadTrait;
use App\Models\Asset;

abstract class AssetBulkAbstract
{
    use BulkUploadTrait;

    abstract protected function getHeaderMap();

    abstract protected function getDefaultTicket();

    /**
     * Return data from csv.
     *
     * @return array
     */
    public function importAssetData(string $path)
    {
        $count = 1;
        $data = $this->getItems($path);
        $csvData = [
            'error' => $data['error'],
            'csvData' => [],
        ];

        if (!empty($data['csvData'])) {
            foreach ($data['csvData'] as $key => $item) {
                if (!count($item)) {
                    continue; //skip empty columns
                }

                $csvData['csvData'][] = $this->generateCSVData($item, $count++);
            }
        }

        return $csvData;
    }

    /**
     * Generate asset data from the csv array.
     *
     * @param string $item
     *
     * @return array
     */
    public function generateCSVData(array $item, int $count)
    {
        $assetData = [];
        foreach ($this->getHeaderMap() as $dbField => $fileHeader) {
            $result = $this->getRelationalValues($item, $dbField, $fileHeader);
            if ($result !== false) {
                $item[$fileHeader] = $result;
            }
            $assetData[$dbField] = !empty($item[$fileHeader]) ? $item[$fileHeader] : null;

            if ($dbField == 'serial_no') {
                $assetData = $this->getAdditionalAssetData($assetData, $item[$fileHeader]);
            }
            if ($dbField == 'parent_asset_tag') {
                $assetData = $this->getAdditionalLinkData($assetData, $item[$fileHeader], 'parent');
            }
            if ($dbField == 'child_asset_tag') {
                $assetData = $this->getAdditionalLinkData($assetData, $item[$fileHeader], 'child');
            }
        }

        $assetData['asset_count'] = $count++;
        session(['asset_count' => $assetData['asset_count']]);

        return compact('assetData');
    }

    /**
     * Get Additonal Asset Data.
     *
     * @return array
     */
    public function getAdditionalAssetData(array $assetData, string $item = '')
    {
        $assetData['asset_id'] = null;
        $assetData['current_asset_status_id'] = null;

        $asset = Asset::where('serial_no', trim($item))->first();
        if ($asset) {
            $assetData['asset_id'] = $asset->id;
            $assetData['current_asset_status_id'] = $asset->asset_status_id;
        }

        return $assetData;
    }

    /**
     * Get Additonal Asset Data.
     *
     * @return array
     */
    public function getAdditionalLinkData(array $assetData, string $item = '', string $type = 'parent')
    {
        $assetData[$type.'_asset_id'] = null;
        $assetData[$type.'_current_asset_status_id'] = null;

        $asset = Asset::where('asset_tag', trim($item))->first();
        if ($asset) {
            $assetData[$type.'_asset_id'] = $asset->id;
            $assetData[$type.'_current_asset_status_id'] = $asset->asset_status_id;
        }

        return $assetData;
    }

    /**
     * Validate Columns have data.
     *
     * @return array
     */
    public function validateCsvColumns(string $path, array $csvData)
    {
        $headerKeys = array_values($this->getHeaderMap());

        $csv = array_map('str_getcsv', file($path, FILE_SKIP_EMPTY_LINES));
        $csvKeys = array_shift($csv);

        $result = [];

        if (empty($csvData)) {
            return 'Please make sure the file contains data';
        }

        $messages = $this->checkFileDifference($csvKeys, $headerKeys);

        return $messages;
    }

    /**
     * Validate Each CSV fields.
     *
     * @return array
     */
    public function validateFields(array $csvData)
    {
        $count = 2;
        foreach ($csvData as $data) {
            $errors[] = $this->csvValidator($data['assetData'], $count++);
        }

        return $errors;
    }

    /**
     * Check csv file difference from the template file.
     *
     * @return string
     */
    public function checkFileDifference(array $csvKeys, array $headerKeys)
    {
        if (count($headerKeys) >= count($csvKeys)) {
            $result = array_diff($headerKeys, $csvKeys);
            $messageString = 'Please make sure the column names are spelled correctly. Columns missing - ';
        } else {
            $result = array_diff($csvKeys, $headerKeys);
            $messageString = 'Uploaded file is not match with template file. Extra columns - ';
        }
        $messages = '';

        if (!empty($result)) {
            foreach ($result as $key => $value) {
                $messageString .= $value.', ';
            }
            $messages = rtrim($messageString, ', ');
        }

        return $messages;
    }
}
