<?php

namespace App\Http\Controllers\Assets\Settings;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\SpecialUpload;
use App\Services\BulkUpload\BulkReturnService;
use App\Services\BulkUpload\SpecialBulkReturnService;
use Illuminate\Support\Facades\Storage;
use App\Http\Requests\CsvFileUploadRequest;
use App\Http\Traits\FileSanitizationTrait;

class BulkReturnController extends Controller
{
    use FileSanitizationTrait;

    public function __construct(protected BulkReturnService $bulkReturnService, protected SpecialBulkReturnService $specialBulkReturnService) {}

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        session(['asset_count' => 0]);

        return view('settings.bulk-return');
    }

    /**
     * Handle the upload of a CSV file for bulk return asset updates.
     *
     * This method processes the uploaded file, stores it in a designated directory,
     * and delegates the file processing to the bulkReturnService.
     *
     * @param \App\Http\Requests\CsvFileUploadRequest $request
     *        The validated request containing the uploaded CSV file.
     *
     * @return mixed
     *         The response from the bulkReturnService after processing the file.
     */
    public function upload(CsvFileUploadRequest $request)
    {
        setUnlimitedExecutionTimeAndMemoryLimit();

        // Get the uploaded file from the request
        $file = $request->file('file');

        // Get the file extension in lowercase
        $extension = strtolower($file->getClientOriginalExtension());

        $fileName = 'return-asset-items-'  . date("m-d-y") . '-' . time() . '.' . $extension;
        $path = $file->storeAs('public/bulk_return', $fileName);

        return $this->bulkReturnService->getViewData(storage_path('app/' . $path), $fileName);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $errors = [];
        $updatedCount = 0;

        if ($request->count == 0) {
            return redirect(route('bulk-return.index'))->with('error', 'Assets cannot be moved.');
        }

        $basePath = storage_path('app/public/bulk_return');
        $filePath = $this->sanitizeFilePath($request->filePath, $basePath);
        $fileName = $this->sanitizeFileName($request->fileName);

        for ($i = 1; $i <= $request->count; $i++) {
            if (!$request->has('asset_id' . $i)) {
                continue; //row was deleted before submitting
            }

            $updateResponse = $this->bulkReturnService->saveData($request->all(), $i);

            if ($updateResponse === false) {
                $errors[] = request('serial_no' . $i);
                continue;
            }

            $updatedCount++;
        }

        $this->bulkReturnService->attachFiletoTicket(request('ticket_no1'), $filePath, $fileName);

        if (empty($errors)) {
            return redirect(route('bulk-return.index'))->with('message', 'Assets returned successfully.');
        }

        if ($request->count != count($errors)) {
            return redirect(route('bulk-return.index'))
                ->with([
                    'message' => "Total {$updatedCount} assets returned successfully.",
                    'error' => 'Assets ' . implode(', ', $errors) . ' cannot be returned.',
                ]);
        }

        return redirect(route('bulk-return.index'))->with('error', 'Assets cannot be returned.');
    }

    /**
     * Special upload function for bulk asset return.
     *
     * This function sets unlimited execution time and memory limit,
     * processes the uploaded file, and stores it in the public/bulk_return directory.
     * It then calls the importAssetData method of the SpecialBulkReturn service
     * to import the data from the file. If there are validation errors,
     * it stores the errors in a file named retrun-error-<date>.txt in the
     * public/bulk_return directory and redirects back to the bulk-return.index route
     * with the errors. If there are other errors, it stores the errors in a
     * file named retrun-error-<date>.txt in the public/bulk_return directory,
     * and redirects back to the bulk-return.index route with the errors and a
     * message indicating that the bulk return was completed with errors.
     * If there are no errors, it redirects back to the bulk-return.index route
     * with a message indicating that the bulk return was completed successfully.
     *
     * @param  \App\Http\Requests\SpecialUpload  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function specialUpload(SpecialUpload $request)
    {
        setUnlimitedExecutionTimeAndMemoryLimit();

        $file   = $request->file('bulk_upload_asset');

        $extension  = strtolower($file->getClientOriginalExtension());
        $fileName   = 'return-asset-items-' . date("m-d-y") . '-' . time() . '.' . $extension;
        $path       = $file->storeAs('public/bulk_return', $fileName);
        $path       = storage_path('app/' . $path);

        $errors = $this->specialBulkReturnService->importAssetData($path, $fileName);

        if (isset($errors['validationErrors']) && !empty($errors['validationErrors'])) {
            Storage::put('public/bulk_retrun/retrun-error-' . date("m-d-y") . '-' . time() . '.txt', json_encode($errors['validationErrors']));

            return redirect(route('bulk-return.index'))->with(['error' => implode(",\n", $errors['validationErrors'])]);
        }

        if ($errors && !isset($errors['validationErrors'])) {
            Storage::put('public/bulk_retrun/retrun-error-' . date("m-d-y") . '-' . time() . '.txt', json_encode($errors));
            $message = 'Bulk Return with errors';

            return redirect(route('bulk-return.index'))->with(['message' => $message, 'error' => json_encode($errors)]);
        }

        return redirect(route('bulk-return.index'))->with('message', 'Bulk return successful.');
    }
}
