<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Models\PatronSupporter;
use App\Models\PatronTier;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class PatronController extends Controller
{
    public function tiers(): JsonResponse
    {
        $tiers = PatronTier::query()
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->orderBy('monthly_amount')
            ->get();

        // Add active supporter count
        $tiers->each(function ($tier): void {
            $tier->supporter_count = PatronSupporter::where('tier_id', $tier->id)
                ->where('status', 'active')
                ->count();
        });

        return response()->json($tiers);
    }

    public function support(Request $request): JsonResponse
    {
        if (! $request->user()) {
            throw new AccessDeniedHttpException('UNAUTH');
        }

        $data = $request->validate([
            'tier_id' => ['required', 'uuid'],
            'payment_id' => ['nullable', 'uuid'],
        ]);

        $tier = PatronTier::where('is_active', true)->findOrFail($data['tier_id']);

        // Cancel any existing active subscription
        PatronSupporter::where('user_id', $request->user()->id)
            ->where('status', 'active')
            ->update(['status' => 'cancelled', 'ended_at' => now()]);

        $supporter = PatronSupporter::create([
            'tenant_id' => $tier->tenant_id,
            'user_id' => $request->user()->id,
            'tier_id' => $tier->id,
            'started_at' => now(),
            'payment_id' => $data['payment_id'] ?? null,
            'status' => 'active',
        ]);

        return response()->json(['data' => $supporter->load('tier')], 201);
    }

    public function cancel(Request $request): JsonResponse
    {
        if (! $request->user()) {
            throw new AccessDeniedHttpException('UNAUTH');
        }

        $count = PatronSupporter::where('user_id', $request->user()->id)
            ->where('status', 'active')
            ->update(['status' => 'cancelled', 'ended_at' => now()]);

        return response()->json(['data' => ['cancelled' => $count]]);
    }

    public function supporters(Request $request): JsonResponse
    {
        $q = PatronSupporter::query()
            ->with(['tier:id,name,color,monthly_amount', 'user:id,name,username'])
            ->where('status', 'active')
            ->orderByDesc('started_at');

        if ($tierId = $request->query('tier_id')) {
            $q->where('tier_id', $tierId);
        }

        $items = $q->paginate((int) $request->query('per_page', 30));

        return response()->json($items);
    }

    public function adminListTiers(Request $request): JsonResponse
    {
        $this->requireAdmin($request);
        $tiers = PatronTier::orderBy('sort_order')->get();
        return response()->json(['data' => $tiers]);
    }

    public function adminStoreTier(Request $request): JsonResponse
    {
        $this->requireAdmin($request);

        $data = $request->validate([
            'name' => ['required', 'string', 'max:100'],
            'monthly_amount' => ['required', 'integer', 'min:1000'],
            'benefits' => ['nullable', 'array'],
            'max_supporters' => ['nullable', 'integer'],
            'color' => ['nullable', 'string', 'max:20'],
            'sort_order' => ['nullable', 'integer'],
            'is_active' => ['nullable', 'boolean'],
        ]);

        $tier = PatronTier::create($data);
        return response()->json(['data' => $tier], 201);
    }

    public function adminUpdateTier(Request $request, string $id): JsonResponse
    {
        $this->requireAdmin($request);
        $tier = PatronTier::findOrFail($id);

        $data = $request->validate([
            'name' => ['sometimes', 'string', 'max:100'],
            'monthly_amount' => ['sometimes', 'integer', 'min:1000'],
            'benefits' => ['nullable', 'array'],
            'max_supporters' => ['nullable', 'integer'],
            'color' => ['nullable', 'string', 'max:20'],
            'sort_order' => ['nullable', 'integer'],
            'is_active' => ['sometimes', 'boolean'],
        ]);

        $tier->update($data);
        return response()->json(['data' => $tier]);
    }

    public function adminDestroyTier(Request $request, string $id): JsonResponse
    {
        $this->requireAdmin($request);
        $tier = PatronTier::findOrFail($id);
        $tier->delete();
        return response()->json(['data' => ['deleted' => true]]);
    }

    private function requireAdmin(Request $request): void
    {
        $user = $request->user();
        if (! $user) {
            throw new AccessDeniedHttpException('UNAUTH');
        }
        if (! ($user->hasRole('super_admin') || $user->hasRole('tenant_admin'))) {
            throw new AccessDeniedHttpException('PERM_DENIED:patron.admin');
        }
    }
}
