<?php

namespace App\Http\Controllers\Assets\Settings;

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

class BulkDamageController extends Controller
{
    use FileSanitizationTrait;

    public function __construct(protected BulkDamageService $bulkStatusUpdate, protected SpecialBulkDamageService $specialBulkStatusUpdate) {}

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

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

    /**
     * Handle the upload of a CSV file for bulk damage asset updates.
     *
     * This method processes the uploaded file, stores it in a specific directory,
     * and delegates the file processing to the bulkStatusUpdate service.
     *
     * @param \App\Http\Requests\CsvFileUploadRequest $request
     *        The validated request containing the uploaded CSV file.
     *
     * @return mixed
     *         The response from the bulkStatusUpdate service 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  = 'damage-asset-items-' . date("m-d-y") . '-' . time() . '.' . $extension;
        $path      = $file->storeAs('public/asset_bulk_damage', $fileName);

        return $this->bulkStatusUpdate->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('on-hand-statuses.index'))->with('error', 'Assets cannot be updated.');
        }

        $basePath = storage_path('app/public/asset_bulk_damage');
        $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->bulkStatusUpdate->saveData($request->all(), $i);
            if ($updateResponse === false) {
                $errors[] = request('serial_no' . $i);
                continue;
            }

            $updatedCount++;
        }

        $this->bulkStatusUpdate->attachFiletoTicket(request('ticket_no1'), $filePath, $fileName);
        if (empty($errors)) {

            return redirect(route('on-hand-statuses.index'))->with('message', 'Assets updated successfully.');
        }

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

        return redirect(route('on-hand-statuses.index'))->with('error', 'Assets cannot be updated.');
    }

    /**
     * Special upload function for bulk asset damage.
     *
     * This function sets unlimited execution time and memory limit,
     * then stores the uploaded file in the public/asset_bulk_damage
     * directory. It then calls the importAssetData method of the
     * SpecialBulkStatusUpdate service to import the data from the file.
     * If there are validation errors, it stores the errors in a file named
     * assign-error-<date>.txt in the public/asset_bulk_damage
     * directory, and redirects back to the on-hand-statuses.index route
     * with the errors. If there are other errors, it stores the errors in a
     * file named assign-error-<date>.txt in the public/asset_bulk_damage
     * directory, and redirects back to the on-hand-statuses.index route
     * with the errors and a message indicating that the bulk asset damage
     * update was completed with errors. If there are no errors, it redirects
     * back to the on-hand-statuses.index route with a message indicating
     * that the bulk asset damage update 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   = 'damage-asset-items-' . date("m-d-y") . '-' . time() . '.' . $extension;
        $path       = $file->storeAs('public/asset_bulk_damage', $fileName);

        $path   = storage_path('app/' . $path);

        //$errors = BulkDamage::importAssetSpecialData($path);
        $errors = $this->specialBulkStatusUpdate->importAssetData($path, $fileName);

        $message = 'Bulk status update completed successfully.';

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

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

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

            return redirect(route('on-hand-statuses.index'))->with(['message' => $message, 'errors' => $errors]);
        }

        return redirect(route('on-hand-statuses.index'))->with(['message' => $message]);
    }
}
