<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Enums\ImportStatus;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreImportRequest;
use App\Http\Resources\ImportJobResource;
use App\Jobs\ValidateImportJob;
use App\Models\ImportJob;
use App\Services\MemberCsvColumns;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use League\Csv\Writer;

class ImportController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $jobs = ImportJob::visibleTo($request->user())
            ->with('branch:id,name,code')
            ->orderByDesc('created_at')
            ->limit(100)
            ->get();

        return ImportJobResource::collection($jobs)->response();
    }

    public function store(StoreImportRequest $request): JsonResponse
    {
        $uuid = Str::uuid()->toString();
        $directory = "imports/{$uuid}";
        Storage::disk('local')->makeDirectory($directory);

        $sourcePath = "{$directory}/source.csv";
        $request->file('file')->move(Storage::disk('local')->path($directory), 'source.csv');

        $job = ImportJob::create([
            'user_id' => $request->user()->id,
            'branch_id' => $request->input('branch_id'),
            'status' => ImportStatus::Pending,
            'source_path' => $sourcePath,
            'options' => $request->input('options', []),
        ]);

        ValidateImportJob::dispatch($job->id);

        return (new ImportJobResource($job))->response()->setStatusCode(Response::HTTP_ACCEPTED);
    }

    public function show(ImportJob $importJob): ImportJobResource
    {
        $this->authorize('view', $importJob);

        return new ImportJobResource($importJob->load('branch:id,name,code'));
    }

    public function errors(ImportJob $importJob): mixed
    {
        $this->authorize('view', $importJob);

        if ($importJob->error_report_path === null) {
            return response()->json(['message' => 'Not found.'], 404);
        }

        return Storage::disk('local')->download($importJob->error_report_path, 'import-errors.csv');
    }

    public function template(): mixed
    {
        $csv = Writer::createFromString('');
        $csv->insertOne(MemberCsvColumns::templateColumns());

        return response($csv->toString(), 200, [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="member-import-template.csv"',
        ]);
    }
}
