<?php

namespace App\Http\Controllers;

use App\Http\Requests\CancelInventoryTransferDocumentDraftRequest;
use App\Http\Requests\ConfirmInventoryTransferDocumentRequest;
use App\Http\Requests\IndexInventoryTransferDocumentRequest;
use App\Http\Requests\QuickInventoryTransferRequest;
use App\Http\Requests\StoreInventoryTransferDocumentRequest;
use App\Http\Requests\UpdateInventoryTransferDocumentRequest;
use App\Models\InventoryTransferDocument;
use App\Services\InventoryTransferDocumentService;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use InvalidArgumentException;

class InventoryTransferDocumentController extends Controller
{
    public function index(IndexInventoryTransferDocumentRequest $request): JsonResponse
    {
        $perPage = min(100, max(5, (int) $request->validated('per_page', 20)));

        $query = InventoryTransferDocument::query()
            ->with([
                'lines',
                'destinationArea:id,name,code',
                'recipientUser:id,name',
                'supplier:id,name',
                'createdByUser:id,name',
            ]);

        if ($request->filled('status')) {
            $query->where('status', $request->validated('status'));
        }

        if ($request->filled('transfer_type')) {
            $query->where('transfer_type', $request->validated('transfer_type'));
        }

        $paginator = $query->orderByDesc('created_at')->paginate($perPage);

        return response()->json([
            'data' => $paginator,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function show(InventoryTransferDocument $inventory_transfer_document): JsonResponse
    {
        $this->authorize('view', $inventory_transfer_document);

        $inventory_transfer_document->load([
            'lines.inventoryProduct.productType',
            'destinationArea',
            'recipientUser:id,name',
            'supplier',
            'createdByUser:id,name',
            'confirmedByUser:id,name',
            'cancelledByUser:id,name',
        ]);

        return response()->json([
            'data' => $inventory_transfer_document,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function quickStore(
        QuickInventoryTransferRequest $request,
        InventoryTransferDocumentService $service
    ): JsonResponse {
        $userId = Auth::id();
        if ($userId === null) {
            return response()->json(['message' => 'No autenticado.'], JsonResponse::HTTP_UNAUTHORIZED);
        }

        $validated = $request->validated();
        $lines = $validated['lines'];
        unset($validated['lines']);

        try {
            $document = $service->createAndConfirm($validated, $lines, $userId);
        } catch (InvalidArgumentException $e) {
            return response()->json([
                'message' => $e->getMessage(),
                'errors' => ['document' => [$e->getMessage()]],
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        return response()->json([
            'data' => $document,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_CREATED);
    }

    public function store(
        StoreInventoryTransferDocumentRequest $request,
        InventoryTransferDocumentService $service
    ): JsonResponse {
        $userId = Auth::id();
        if ($userId === null) {
            return response()->json(['message' => 'No autenticado.'], JsonResponse::HTTP_UNAUTHORIZED);
        }

        $validated = $request->validated();
        $lines = $validated['lines'];
        unset($validated['lines']);

        $document = $service->createDraft($validated, $lines, $userId);

        return response()->json([
            'data' => $document,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_CREATED);
    }

    public function update(
        UpdateInventoryTransferDocumentRequest $request,
        InventoryTransferDocument $inventory_transfer_document,
        InventoryTransferDocumentService $service
    ): JsonResponse {
        $validated = $request->validated();
        $lines = $validated['lines'];
        unset($validated['lines']);

        try {
            $document = $service->updateDraft($inventory_transfer_document, $validated, $lines);
        } catch (InvalidArgumentException $e) {
            return response()->json([
                'message' => $e->getMessage(),
                'errors' => ['status' => [$e->getMessage()]],
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        return response()->json([
            'data' => $document,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function confirm(
        ConfirmInventoryTransferDocumentRequest $request,
        InventoryTransferDocument $inventory_transfer_document,
        InventoryTransferDocumentService $service
    ): JsonResponse {
        $userId = Auth::id();
        if ($userId === null) {
            return response()->json(['message' => 'No autenticado.'], JsonResponse::HTTP_UNAUTHORIZED);
        }

        try {
            $document = $service->confirm($inventory_transfer_document, $userId);
        } catch (InvalidArgumentException $e) {
            return response()->json([
                'message' => $e->getMessage(),
                'errors' => ['document' => [$e->getMessage()]],
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        return response()->json([
            'data' => $document,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    public function cancelDraft(
        CancelInventoryTransferDocumentDraftRequest $request,
        InventoryTransferDocument $inventory_transfer_document,
        InventoryTransferDocumentService $service
    ): JsonResponse {
        $userId = Auth::id();
        if ($userId === null) {
            return response()->json(['message' => 'No autenticado.'], JsonResponse::HTTP_UNAUTHORIZED);
        }

        try {
            $document = $service->cancelDraft($inventory_transfer_document, $userId);
        } catch (InvalidArgumentException $e) {
            return response()->json([
                'message' => $e->getMessage(),
                'errors' => ['status' => [$e->getMessage()]],
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        return response()->json([
            'data' => $document,
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }
}
