<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\Pwa;

use App\Http\Controllers\Api\Pwa\Traits\RoleAwareQueries;
use App\Http\Controllers\Controller;
use App\Models\Expense;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class ApprovalController extends Controller
{
    use RoleAwareQueries;

    /**
     * GET /api/pwa/approvals/pending
     *
     * Lista operaciones pendientes de aprobación para el supervisor/admin.
     *
     * Contexto: El modelo CreditRestructureLog no implementa flujo de aprobación
     * (las reestructuraciones son ejecutadas directamente por admin/supervisor).
     * Las aprobaciones pendientes son Gastos (Expense) que superan el umbral
     * de monto configurado y requieren autorización del supervisor.
     */
    public function pendingOperations(Request $request): JsonResponse
    {
        if (! $this->canViewAllCredits($request)) {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $user = $request->user();
        $companyId = $user->company_id;

        $pending = Expense::with([
            'user:id,name',
            'credit:id,client_id',
            'credit.client:id,name',
        ])
            ->where('company_id', $companyId)
            ->where('requires_approval', true)
            ->where('approval_status', Expense::APPROVAL_PENDING)
            ->orderBy('created_at', 'desc')
            ->limit(50)
            ->get();

        $total = Expense::where('company_id', $companyId)
            ->where('requires_approval', true)
            ->where('approval_status', Expense::APPROVAL_PENDING)
            ->count();

        return response()->json([
            'data' => $pending->map(fn (Expense $e) => $this->formatExpense($e)),
            'meta' => [
                'total' => $total,
                'showing' => $pending->count(),
                'has_more' => $total > $pending->count(),
            ],
        ]);
    }

    /**
     * POST /api/pwa/approvals/{id}/approve
     *
     * Aprueba un gasto pendiente. Solo supervisor/admin.
     * Opcionalmente acepta { notes: string } en el body.
     */
    public function approve(Request $request, int $id): JsonResponse
    {
        if (! $this->canViewAllCredits($request)) {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $request->validate([
            'notes' => ['nullable', 'string', 'max:500'],
        ]);

        $expense = Expense::where('company_id', $request->user()->company_id)
            ->findOrFail($id);

        if (! $expense->isPendingApproval()) {
            return response()->json([
                'message' => 'Este gasto ya fue procesado (aprobado o rechazado).',
            ], 422);
        }

        $expense->approve($request->input('notes'));

        return response()->json([
            'message' => 'Gasto aprobado correctamente.',
            'expense_id' => $expense->id,
            'expense' => $this->formatExpense($expense->fresh()),
        ]);
    }

    /**
     * POST /api/pwa/approvals/{id}/reject
     *
     * Rechaza un gasto pendiente. Solo supervisor/admin.
     * Requiere { reason: string } en el body.
     */
    public function reject(Request $request, int $id): JsonResponse
    {
        if (! $this->canViewAllCredits($request)) {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $request->validate([
            'reason' => ['required', 'string', 'max:500'],
        ]);

        $expense = Expense::where('company_id', $request->user()->company_id)
            ->findOrFail($id);

        if (! $expense->isPendingApproval()) {
            return response()->json([
                'message' => 'Este gasto ya fue procesado (aprobado o rechazado).',
            ], 422);
        }

        $expense->reject($request->input('reason'));

        return response()->json([
            'message' => 'Gasto rechazado.',
            'expense_id' => $expense->id,
            'expense' => $this->formatExpense($expense->fresh()),
        ]);
    }

    /**
     * Formatea un Expense para la respuesta JSON.
     */
    private function formatExpense(Expense $e): array
    {
        return [
            'id' => $e->id,
            'type' => 'expense',
            'type_label' => 'Gasto',
            'category' => $e->getRawOriginal('category'),
            'category_label' => $e->category?->getLabel() ?? $e->getRawOriginal('category'),
            'amount' => (float) $e->amount,
            'description' => $e->notes,
            'credit_id' => $e->credit_id,
            'client_name' => $e->credit?->client?->name,
            'created_by' => $e->user?->name,
            'created_at' => $e->created_at?->toIso8601String(),
            'approval_status' => $e->approval_status,
            'approval_notes' => $e->approval_notes,
        ];
    }
}
