<?php

namespace App\Http\Controllers\Assets\Settings;

use App\Services\BulkUpload\SpecialBulkAssetAttributeService;
use App\Services\BulkUpload\BulkAssetAttributeService;
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 BulkAssetAttributeUpdateController extends Controller
{
    use FileSanitizationTrait;

    public function __construct(protected BulkAssetAttributeService $bulkAssetAttributeService, protected SpecialBulkAssetAttributeService $specialBulkAssetAttributeService) {}

    public function index()
    {
        session(['asset_count' => 0]);

        return view('settings.bulk-asset-attribute-update');
    }

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

        return $this->bulkAssetAttributeService->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;
        $ticketNo = '';
        $filePath = '';
        $fileName = '';
        $basePath = storage_path('app/public/asset_bulk_attribute_update');

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

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

            $requestData = json_decode(request('data' . $i), true);

            // Set ticket, filePath, and fileName from the first row
            $ticketNo = $ticketNo ?: ($requestData['ticket_no'] ?? null);
            $filePath = $filePath ?: $this->sanitizeFilePath($requestData['filePath'], $basePath);
            $fileName = $fileName ?: $this->sanitizeFileName($requestData['fileName']);

            $updateResponse = $this->bulkAssetAttributeService->saveData($requestData, $i);
            if ($updateResponse === false) {
                $errors[] = $requestData['serial_no'] ?? ''; // Add serial_no if available
                continue;
            }

            $updatedCount++;
        }

        $this->bulkAssetAttributeService->attachFiletoTicket($ticketNo, $filePath, $fileName);

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

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

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

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

        $errors = $this->specialBulkAssetAttributeService->importAssetSpecialData($path, $fileName);

        if (isset($errors['validationErrors']) && !empty($errors['validationErrors'])) {
            Storage::put('public/asset_bulk_attribute_update/attribute-error-' . date("m-d-y") . '-' . time() . '.txt', json_encode($errors['validationErrors']));
            return redirect()->route('bulk-asset-attribute.index')->with(['error' => implode(",\n", $errors['validationErrors'])]);
        }

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

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

        return redirect()->route('bulk-asset-attribute.index')->with('message', 'Bulk asset attribute updated successfully.');
    }
}
