<?php

namespace App\Http\Controllers\SoftwareLicense;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Responses\DataTableJsonResponse;
use App\Models\SoftwareLicense\SoftwareLicenseKey;
use App\Rules\SoftwareLicense\LicenseKeyFormat;
use App\Services\SoftwareLicense\LicenseKeyService;
use App\Services\SoftwareLicense\LicenseHistoryService;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\DB;

/**
 * Software License Key Controller
 */
class SoftwareLicenseKeyController extends Controller
{

    /**
     * Constructor for the class.
     *
     * @param LicenseKeyService     $licenseKeyService     An instance of LicenseKeyService used for managing license keys.
     * @param LicenseHistoryService $licenseHistoryService An instance of LicenseHistoryService used for managing license history.
     */
    public function __construct(protected LicenseKeyService $licenseKeyService, protected LicenseHistoryService $licenseHistoryService)
    {
    }

    /**
     * List Software License keys
     *
     * @param object $request
     *
     * @return object
     */
    public function list(Request $request)
    {
        $licenseId      = $request['form']['id'];
        $keyData        = $this->licenseKeyService->getAllLicenseKeys($licenseId);
        $licenseKeys    = $keyData['licenseKeys'];
        $totalData      = $keyData['count'];

        $start  = request('start');
        $data   = [];

        if (!empty($licenseKeys)) {
            $data = $this->licenseKeyService->getLicensesKeyData($licenseKeys, $start, $data);
        }

        return new DataTableJsonResponse($request->input('draw'), $data, $totalData);
    }

    /**
     * Remove Software License keys
     *
     * @param object $request
     *
     * @return object
     */
    public function remove(Request $request)
    {
        return $this->licenseKeyService->removeKeyFromLicense($request->id);
    }

    /**
     * Download License Key
     *
     * @param int $id The identifier for the license key to be downloaded
     *
     * @return \Symfony\Component\HttpFoundation\BinaryFileResponse The response containing the file download.
     */
    public function download($id)
    {
        $licenseKey = $this->licenseKeyService->getLicenseKey($id);

        return response()->download(storage_path('app/public/software-assets/' . $licenseKey->file_name));
    }

    /**
     * Add new keys to the license
     *
     * @param object $request
     *
     * @return object
     */
    public function add(Request $request)
    {

        DB::beginTransaction();
        try {
            if ($request->has('license_key')  && $request->license_key) {
                $this->licenseKeyService->storeLicenseKey([$request->license_key], $request->software_license_id, $request->key_usage_type, $request->users_allowed_for_key ?? null);
                DB::commit();
                return redirect()->route('software-assets.edit', $request->software_license_id)->with('message', 'License key added successfully.');
            }

            if ($request->has('license_keys')  && $request->license_keys) {
                $countAdded = $this->licenseKeyService->storeLicenseKey(explode(PHP_EOL, $request->license_keys), $request->software_license_id, $request->key_usage_type, $request->users_allowed_for_key);
                DB::commit();
                return redirect()->route('software-assets.edit', $request->software_license_id)->with('message', $countAdded . ' License key(s) added successfully.');
            }

            if ($request->hasfile('software_liceneses_keys')) {
                $extension = strtolower(request()->file('software_liceneses_keys')->getClientOriginalExtension());
                if ($extension != 'csv') {
                    return redirect()->route('software-assets.edit', $request->software_license_id)->with('error', 'Please upload a csv file.');
                }
                $path = request()->file('software_liceneses_keys')->storeAs('public/software-assets', 'software_liceneses_keys-' . time() . '.' . $extension);
                $countAdded = $this->licenseKeyService->saveLicenseKeyDocument(storage_path('app/' . $path), $request->software_license_id, $request->key_usage_type, $request->users_allowed_for_key);
                DB::commit();
                if (is_bool($countAdded['licensesUsed'])) {
                    return redirect()->route('software-assets.edit', $request->software_license_id)->with('error', 'Please check the uploaded file.');
                }
                return redirect()->route('software-assets.edit', $request->software_license_id)->with($countAdded['licensesUsed'] ? 'message' : 'error', ($countAdded['licensesUsed'] ? ($countAdded['licensesUsed'] . ' License key(s) uploaded successfully.') : '') . ($countAdded['rejected'] ? ($countAdded['rejected'] . ' key(s) rejected as the # of licenses purchased reached or due to invalid key format.') : ''));
            }
        } catch (Exception $e) {
            // dd($e->getMessage());
            DB::rollBack();
            return redirect()->route('software-assets.edit', $request->software_license_id)->with('error', 'Opertaion failed');
        }

        return redirect()->route('software-assets.edit', $request->software_license_id)->with('error', 'Opertaion failed');
    }

    /**
     * Loads the edit key form
     * @return [type]
     */
    public function editIndividual()
    {
        $licenseKey = $this->licenseKeyService->getLicenseKey(request('id'));
        return view('software-license.partials.individual-key-edit', compact('licenseKey'))->render();
    }

    /**
     * Update individual licenses
     * @return [type]
     */
    public function updateIndividual()
    {
        request()->validate([
            'license_key' => [new LicenseKeyFormat('/^[a-zA-Z0-9,_ -]+$/i')],
        ]);
        DB::beginTransaction();
        try {
            $licenseKey = $this->licenseKeyService->updateIndividual(request()->all());
            DB::commit();
            return redirect()->route('software-assets.edit', $licenseKey->software_license_id)->with('message', 'License key updated successfully.');
        } catch (Exception $e) {
            // dd($e->getMessage());
            DB::rollback();
            $licenseKey = $this->licenseKeyService->getLicenseKey(request('license_key_id'));

            return redirect()->route('software-assets.edit', $licenseKey->software_license_id)->with('error', 'Opertaion failed');
        }
    }
}
