<?php

namespace App\Http\Controllers\Assets\Settings;

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

class BulkLinkController extends Controller
{
    use FileSanitizationTrait;

    public function __construct(protected BulkLinkService $bulkLink, protected SpecialBulkLinkService $specialBulkLink) {}

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('settings.bulk-link');
    }

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

        return $this->bulkLink->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-link.index'))->with('error', 'Assets cannot be moved.');
        }

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

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

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

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

            $updatedCount++;
        }

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

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

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

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

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

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

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

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

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

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

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