<?php

namespace App\Console\Commands;

use App\Events\IntegrationSyncHistory;
use App\Services\Integrations\IntuneIntegration;
use Illuminate\Console\Command;
use App\Models\IntuneComputer;
use App\Notifications\Slack;
use App\Services\DiscoveryTools\Intune\IntuneSyncService;
use Illuminate\Support\Facades\Notification;

class IntuneDataSync extends Command
{

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'IntuneDataSync:run';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Download data from Intune Graph API';


    /**
     * Create a new command instance.
     *
     * @param IntuneIntegration $intuneApiService The Intune API service instance.
     * @param IntuneSyncService $service          The Intune sync service instance.
     *
     * @return void
     */
    public function __construct(protected IntuneIntegration $intuneApiService, protected IntuneSyncService $service)
    {
        parent::__construct();
    }


    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $nextPageLink = null;
        $assetCount = 0;

        // For Checking Connection status.
        $connectionStatus = $this->intuneApiService->getWindowsManagedDevices($nextPageLink);

        if ($this->hasErrorInReponse($connectionStatus)) {
            $this->sendNotification('FAILED! Intune connection failed.');
            return $this->info("exiting from execution");
        }

        IntuneComputer::truncate();

        while (1) {
            $devices = $this->intuneApiService->getWindowsManagedDevices($nextPageLink);

            if ($this->hasErrorInReponse($devices)) {
                return $this->info("exiting from execution");
            }

            $assetCount = $this->saveData($devices['devices']['value']);

            $nextPageLink = $devices['devices']['@odata.nextLink'] ?? null;

            if (!$nextPageLink) {
                break; //exit the loop
            }
        }

        $message = "Intune sync Completed. Total $assetCount devices added.";
        // $this->autoResassignDiscrepacyDevices();

        $this->sendNotification($message);

        // Event to add sync history(sync_name, sync_status, notes).
        event(new IntegrationSyncHistory('intune'));

        return $this->info("Intune sync Completed. Total $assetCount devices added.");
    }


    /**
     * Saves the data of Intune managed devices.
     *
     * @param array $items The array of Intune managed devices to be saved.
     *
     * @return int The number of devices saved.
     */
    public function saveData($items)
    {
        $count = 0;

        foreach ($items as $item) {
            $this->service->updateIntuneDevices($item);
            $count++;
        }

        return $count;
    }


    /**
     * Checks if there is an error in the response from Intune API.
     *
     * @param array $devices The response from the Intune API.
     *
     * @return bool True if there is an error in the response, false otherwise.
     */
    public function hasErrorInReponse($devices)
    {
        if (isset($devices['token_error']) || isset($devices['error'])) {
            $this->sendNotification(false);

            return true;
        }

        return false;
    }


    /**
     * Re assign the user for user mismatch devices.
     *
     * @return mixed The result of the reassignment operation.
     */
    private function autoResassignDiscrepacyDevices()
    {
        return $this->service->reassignAssets();
    }


    /**
     * Sends a notification message via Slack.
     *
     * @param string $message The message content to be sent via Slack.
     *
     * @return void
     */
    public function sendNotification($message)
    {
        if (config('teqtivity-notification-mails.slack')) {
            Notification::route('slack', config('teqtivity-notification-mails.slack'))->notify(new Slack($message));
        }
    }
}
