<?php

namespace App\Services\DiscoveryTools\Jamf;

abstract class AbstractJamfService
{
    abstract public function data();
    abstract public function exportData();
    /**
     * Executing the query
     * @param $devices Query
     * @return Query Result
     */
    public function getOutputData($devices, $order)
    {
        $start = request('start');
        $limit = request('length');
        if ($limit != -1) {
            $devices = $devices->offset($start)->limit($limit);
        }
        $devices->orderBy($order, 'DESC');

        return $devices->get();
    }

    /**
     * Generating data table data from qurey result
     * @param $users Query Result
     * @param $start Starting index
     * @param $data Collection valriable that will return
     *
     * @return array
     */
    public function getReportData($assets, $start, $data = [])
    {
        $parentIndex = $start;

        foreach ($assets as $key => $asset) {
            $parentIndex++;
            $userLink = $asset->user_id ? route('users.show', $asset->user_id) : '#';
            $nestedData = $this->getNestedData($asset, $parentIndex, $userLink);
            $data[] = $nestedData;
        }

        return $data;
    }

    /**
     * Taking the input data
     * @return Array
     */
    public function getInputData()
    {
        return [

            'serial_no'                => isset(request('form')['serial_no']) ? request('form')['serial_no'] : '',
            'host_name'                => isset(request('form')['host_name']) ? request('form')['host_name'] : '',
            'mac_address'              => isset(request('form')['mac_address']) ? request('form')['mac_address'] : '',
            'model'                    => isset(request('form')['model']) ? request('form')['model'] : '',
            'asset_type'               => isset(request('form')['asset_type']) ? request('form')['asset_type'] : '',
            'asset_status'             => isset(request('form')['asset_status']) ? request('form')['asset_status'] : '',
            'manufacturer'             => isset(request('form')['manufacturer']) ? request('form')['manufacturer'] : '',
            'make_and_model'           => isset(request('form')['make_and_model']) ? request('form')['make_and_model'] : '',
            'teqtivity_asset'          => isset(request('form')['teqtivity_asset']) ? request('form')['teqtivity_asset'] : '',
            'location_id'              => isset(request('form')['room_name']) ? request('form')['room_name'] : '',
            'asset_status_id'          => isset(request('form')['asset_status']) ? request('form')['asset_status'] : '',

            'jamf_user'                => isset(request('form')['jamf_user']) ? request('form')['jamf_user'] : '',
            'user_status_jamf'         => isset(request('form')['user_status_jamf']) ? request('form')['user_status_jamf'] : '',
            'user_department_jamf'     => isset(request('form')['user_department_jamf']) ? request('form')['user_department_jamf'] : '',
            'work_location_jamf'       => isset(request('form')['work_location_jamf']) ? request('form')['work_location_jamf'] : '',

            'user'                     => isset(request('form')['user']) ? request('form')['user'] : '',
            'user_status'              => isset(request('form')['user_status']) ? request('form')['user_status'] : '',
            'user_department'          => isset(request('form')['user_department']) ? request('form')['user_department'] : '',
            'work_location'            => isset(request('form')['work_location']) ? request('form')['work_location'] : '',

            'last_seen_from'           => isset(request('form')['last_seen_from']) ? request('form')['last_seen_from'] : '',
            'last_seen_to'             => isset(request('form')['last_seen_to']) ? request('form')['last_seen_to'] : '',


            'platform'                 => isset(request('form')['platform']) ? request('form')['platform'] : '',
            'phone_number'             => isset(request('form')['phone_number']) ? request('form')['phone_number'] : '',

            'processor'                => isset(request('form')['processor']) ? request('form')['processor'] : '',
            'disk_capacity'               => isset(request('form')['disk_capacity']) ? request('form')['disk_capacity'] : '',

            'imei'                     => isset(request('form')['imei']) ? request('form')['imei'] : '',
            'carrier'                  => isset(request('form')['carrier']) ? request('form')['carrier'] : '',
            'carrier_country'          => isset(request('form')['carrier_country']) ? request('form')['carrier_country'] : '',

            'os_version'               => isset(request('form')['os_version']) ? request('form')['os_version'] : '',


        ];
    }

    /**
     * Taking the filters for Report generator Export
     *
     * @return Array
     */
    public function getExportInputData()
    {
        return [
            'serial_no'                => request('serial_no') ??  '',
            'host_name'                => request('host_name') ??  '',
            'mac_address'              => request('mac_address') ??  '',
            'model'                    => request('model') ??  '',
            'asset_type'               => request('asset_type') ??  '',
            'asset_status'             => request('asset_status') ?? '',
            'manufacturer'             => request('manufacturer') ??  '',
            'make_and_model'           => request('make_and_model') ??  '',
            'teqtivity_asset'          => request('teqtivity_asset') ??  '',
            'location_id'              => request('room_name') ??  '',
            'asset_status_id'          => request('asset_status') ??  '',

            'jamf_user'                => request('jamf_user') ??  '',
            'user_status_jamf'         => request('user_status_jamf') ??  '',
            'user_department_jamf'     => request('user_department_jamf') ??  '',
            'work_location_jamf'       => request('work_location_jamf') ??  '',

            'user'                     => request('user') ??  '',
            'user_status'              => request('user_status') ??  '',
            'user_department'          => request('user_department') ??  '',
            'work_location'            => request('work_location') ??  '',

            'last_seen_from'           => request('last_seen_from') ??  '',
            'last_seen_to'             => request('last_seen_to') ??  '',


            'platform'                 => request('platform') ??  '',
            'phone_number'             => request('phone_number') ??  '',

            'processor'                => request('processor') ?? '',
            'disk_capacity'               => request('disk_capacity') ?? '',

            'imei'                     => request('imei') ??  '',
            'carrier'                  => request('carrier') ?? '',
            'carrier_country'          => request('carrier_country') ?? '',

            'os_version'               =>  request('os_version') ?? request('os_version'),
        ];
    }

    public function filterDevices($assets, $inputData)
    {
        $assets     = $this->repository->filterRelation($assets, 'serial_no', $inputData['serial_no']);
        $assets     = $this->repository->filterRelation($assets, 'model', $inputData['model']);
        $assets     = $this->repository->filterRelation($assets, 'os_version', $inputData['os_version']);
        $assets     = $this->repository->filterRelation($assets, 'processor', $inputData['processor']);
        $assets     = $this->repository->filterRelation($assets, 'disk_capacity', $inputData['disk_capacity']);
        $assets     = $this->repository->filterRelation($assets, 'mac_address', $inputData['mac_address']);
        $assets     = $this->repository->filterRelation($assets, 'jamf_email', $inputData['jamf_user']);

        $assets     = $this->repository->filterWithAssetMakeAndModelFields($assets, 'manufacturer_id', $inputData['manufacturer']);
        $assets     = $this->repository->filterWithCheckIn($assets, $inputData['last_seen_from'], $inputData['last_seen_to']);

        $assets     = $this->repository->filterWithAssetFields($assets, 'asset_status_id', $inputData['asset_status']);
        $assets     = $this->repository->filterWithAssetFields($assets, 'make_and_model_id', $inputData['make_and_model']);
        $assets     = $this->repository->filterWithAssetFields($assets, 'location_id', $inputData['location_id']);
        $assets     = $this->repository->filterWithAssetFields($assets, 'user_id', $inputData['user']);
        $assets     = $this->repository->filterWithAssetFields($assets, 'asset_type_id', $inputData['asset_type']);

        $assets     = $this->repository->filterWithUserFields($assets, 'status', $inputData['user_status_jamf']);
        $assets     = $this->repository->filterWithUserFields($assets, 'city', $inputData['work_location_jamf']);
        $assets     = $this->repository->filterWithUserFields($assets, 'department_id', $inputData['user_department_jamf']);

        $assets     = $this->repository->filterWithTeqtivityUserFields($assets, 'department_id', $inputData['user_department']);
        $assets     = $this->repository->filterWithTeqtivityUserFields($assets, 'status', $inputData['user_status']);
        $assets     = $this->repository->filterWithTeqtivityUserFields($assets, 'city', $inputData['work_location']);
        $assets     = $this->repository->filterTeqtivityAssetOrNot($assets, $inputData['teqtivity_asset']);


        return $assets;
    }

    /**
     * Generating data to export
     * @param $assets Query Result
     * @param $start Starting index
     * @param $data Collection valriable that will return
     * @param $requiredColumns colums to be shown in export file

     * @return array
     */
    public function getReportExportData($assets, $start, $data, $requiredColumns)
    {
        $parentIndex = $start;

        foreach ($assets as $key => $asset) {
            $parentIndex++;
            $nestedData = $this->getExportNestedData($asset, $requiredColumns);
            $data[] = $nestedData;
        }
        return $data;
    }

    public function getNestedData($asset, $index, $userLink)
    {
        $userLink   = $asset->user_id ? route('users.show', $asset->user_id) : 'javascript:void(0)';
        $assetLink  = $asset->asset ? route('assets.show', $asset->asset->id) : 'javascript:void(0)';

        $serialNo  = $asset->asset ? ("<a href=$assetLink>" . $asset->serial_no . "</a>") : $asset->serial_no;
        $jamfUser = $asset->user_id ? ("<a href=$userLink>" . $asset->jamf_email . "</a>") : $asset->jamf_email;

        $teqtivityUser = isset($asset->asset) ? (isset($asset->asset->user) ? ("<a href=" . route('users.show', $asset->asset->user_id) . "> " . $asset->asset->user->first_name . ' - ' . $asset->asset->user->email . "</a>") : '') : '';

        $nestedData['id']           = $index;
        $nestedData['serial_no']    = $serialNo;
        $nestedData['asset_type'] = optional(optional($asset->asset)->assetType)->name;
        $nestedData['manufacturer_teqtivity']     = optional(optional(optional($asset->asset)->makeAndModel)->manufacturer)->name;
        $nestedData['hardware_teqtivity']            = optional(optional($asset->asset)->makeAndModel)->name;
        $nestedData['teqtivity_asset'] = $asset->asset_id ? 'Yes' : 'No';
        $nestedData['location_teqtivity']     = optional(optional($asset->asset)->location)->room_name;
        $nestedData['asset_status_teqtivity']     = optional(optional($asset->asset)->assetStatus)->name;

        $nestedData['jamf_user']  = $jamfUser;
        $nestedData['jamf_user_status']  = isset($asset->user) ? (optional($asset->user)->status == 1 ? 'Active' : 'Terminated') : '';
        $nestedData['jamf_user_department']  = optional(optional($asset->user)->department)->name;
        $nestedData['jamf_user_work_location']  = optional($asset->user)->city;

        $nestedData['teqtivity_user']   = $teqtivityUser;
        $nestedData['teqtivity_user_status']  = isset($asset->asset->user) ? (optional(optional($asset->asset)->user)->status == 1 ? 'Active' : 'Terminated') : '';
        $nestedData['teqtivity_user_department']  = optional(optional(optional($asset->asset)->user)->department)->name;
        $nestedData['teqtivity_user_work_location']  = optional(optional($asset->asset)->user)->city;

        $nestedData['hardware_jamf']            = $asset->model;
        $nestedData['processor_jamf']        = $asset->processor;
        $nestedData['hard_drive']  = $asset->disk_capacity;
        $nestedData['mac_address_jamf']      = $asset->mac_address;

        $nestedData['computer_name'] = $asset->name;
        $nestedData['checkin_date'] = $asset->checkin_date;
        $nestedData['os_version']   = $asset->os_version;
        $nestedData['os_build']     = $asset->os_build;

        $nestedData['jss_id']         = $asset->udid;
        $nestedData['last_modified_date']   = $asset->latestAssetHistory ?  $asset->latestAssetHistory->updated_at : '';
        $nestedData['create_asset']     = $this->getCreateAssetButton($asset);
        $nestedData['update_asset']     = $this->getUpdateDiscoveryAssetButton($asset->asset, optional($asset->asset)->assetStatus);

        return $nestedData;
    }

    /**
     * Creating array for export data
     * @param $asset Query Result
     * @param $requiredColumns columns to be added in export file
     *
     * @return array
     */
    public function getExportNestedData($asset, $requiredColumns)
    {

        $nestedData['Serial # (Jamf)'] = $asset->serial_no;
        $nestedData['Asset Type (Teqtivity)'] = optional(optional($asset->asset)->assetType)->name;
        $nestedData['Manufacturer (Teqtivity)'] = optional(optional(optional($asset->asset)->makeAndModel)->manufacturer)->name;
        $nestedData['Hardware Standard (Teqtivity)'] = optional(optional($asset->asset)->makeAndModel)->name;
        $nestedData['Asset Location (Teqtivity)'] = optional(optional($asset->asset)->location)->room_name;
        $nestedData['Asset Status (Teqtivity)'] = optional(optional($asset->asset)->AssetStatus)->name;
        $nestedData['User (Jamf)'] = $asset->jamf_email;
        $nestedData['User Status (Jamf)'] = isset($asset->user) ? (optional($asset->user)->status == 1 ? 'Active' : 'Terminated') : '';
        $nestedData['User Department (Jamf)'] = optional(optional($asset->user)->department)->name;
        $nestedData['User Work Location (Jamf)'] = optional($asset->user)->city;
        $nestedData['User (Teqtivity)'] = optional(optional($asset->asset)->user)->first_name . ' - ' . optional(optional($asset->asset)->user)->email;
        $nestedData['User Status (Teqtivity)'] = isset($asset->asset->user) ? (optional(optional($asset->asset)->user)->status == 1 ? 'Active' : 'Terminated') : '';
        $nestedData['User Department (Jamf)'] = optional(optional(optional($asset->asset)->user)->department)->name;
        $nestedData['User Work Location (Jamf)'] = optional(optional($asset->asset)->user)->city;
        $nestedData['Hardware Standard (Jamf)'] = $asset->model;
        $nestedData['Processor (Jamf)'] = $asset->processor;
        $nestedData['Hard Drive (Jamf)'] = $asset->disk_capacity;
        $nestedData['MAC Address (Jamf)'] = $asset->mac_address;
        $nestedData['Last Seen'] = $asset->checkin_date;
        $nestedData['Last Modified Date'] = $asset->latestAssetHistory ?  $asset->latestAssetHistory->updated_at : '';


        $nestedData['Computer Name'] = $asset->name;
        $nestedData['OS Version']   = $asset->os_version;
        $nestedData['Last Check In'] = $asset->checkin_date;
        $nestedData['os_build']     = $asset->os_build;
        $nestedData['JSS ID']       = $asset->udid;



        foreach ($requiredColumns as $key => $column) {
            $data[$column] =  $nestedData[$column];
        }

        return $data;
    }

    /**
     * Generates the function comment for the given function body.
     *
     * @param mixed $asset The asset parameter.
     * @param mixed $assetStatus The asset status parameter.
     * @return string The generated HTML string.
     */
    public function getUpdateDiscoveryAssetButton($asset, $assetStatus)
    {
        if (auth()->user()->can('IT Assets Edit') && $asset) {
            return '<a href="javascript:;" data-asset="' . $asset->id . '" data-asset-serial="' . $asset->serial_no . '" data-asset-current-status="' . optional($assetStatus)->slug . '" data-parent-asset="' . $asset->parent_asset_id . '" class="btn btn-primary btn-sm update-discrepancy-asset">Update Asset</a>';
        }
        return '';
    }

    /**
     * Set up Create Asset Button
     * @param mixed $asset
     */
    public function getCreateAssetButton($asset)
    {
        if (auth()->user()->can('IT Assets Edit') && $asset) {
            return '<a href="javascript:;" data-asset="' . $asset->id . '" data-asset-serial="' . $asset->serial_no . '" class="btn btn-primary btn-sm create-asset">Create Asset</a>';
        }
        return '';
    }
}
