<?php

namespace App\Http\Controllers\Owner;

use App\Http\Controllers\Controller;
use App\Models\ApiToken;
use App\Models\Organization;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

class SettingsController extends Controller
{
    private function ensureOrganization(Request $request): Organization
    {
        $owner = $request->user();

        if (empty($owner->organization_id)) {
            throw ValidationException::withMessages([
                'organization' => 'Tu usuario no tiene organización asignada.',
            ]);
        }

        $organization = Organization::query()->find($owner->organization_id);

        if (! $organization) {
            throw ValidationException::withMessages([
                'organization' => 'No se encontró la organización asociada.',
            ]);
        }

        return $organization;
    }

    public function index(Request $request)
    {
        $owner = $request->user();
        $organization = null;
        $apiTokens = collect();

        if (! empty($owner->organization_id)) {
            $organization = Organization::query()->find($owner->organization_id);
            $apiTokens = $owner->apiTokens()
                ->latest('id')
                ->get();
        }

        return view('content.owner.settings.index', [
            'organization' => $organization,
            'apiTokens' => $apiTokens,
        ]);
    }

    public function update(Request $request)
    {
        try {
            $organization = $this->ensureOrganization($request);
        } catch (ValidationException $e) {
            return redirect()
                ->route('owner.settings.index')
                ->withErrors(['google_maps_api_key' => $e->errors()['organization'][0] ?? 'No se pudo validar la organización.']);
        }

        $validated = $request->validate([
            'google_maps_api_key' => ['nullable', 'string', 'max:255'],
            'gemini_api_key' => ['nullable', 'string', 'max:255'],
            'google_maps_country' => ['nullable', 'string', 'size:2'],
            'replace_keys' => ['nullable', 'boolean'],
        ]);

        $replaceKeys = (bool) ($validated['replace_keys'] ?? false);

        if ($replaceKeys) {
            $organization->google_maps_api_key = $validated['google_maps_api_key'] ?: null;
            $organization->gemini_api_key = $validated['gemini_api_key'] ?: null;
        } else {
            if (! empty($validated['google_maps_api_key'])) {
                $organization->google_maps_api_key = $validated['google_maps_api_key'];
            }

            if (! empty($validated['gemini_api_key'])) {
                $organization->gemini_api_key = $validated['gemini_api_key'];
            }
        }

        if (! empty($validated['google_maps_country'])) {
            $organization->google_maps_country = strtolower($validated['google_maps_country']);
        }

        $organization->save();

        return redirect()
            ->route('owner.settings.index')
            ->with('status', 'Configuración de APIs guardada correctamente.');
    }

    public function storeApiToken(Request $request)
    {
        try {
            $organization = $this->ensureOrganization($request);
        } catch (ValidationException $e) {
            return redirect()
                ->route('owner.settings.index')
                ->withErrors(['api_token' => $e->errors()['organization'][0] ?? 'No se pudo validar la organización.']);
        }

        $validated = $request->validate([
            'name' => ['required', 'string', 'max:120'],
        ]);

        [$token, $plainTextToken] = ApiToken::issueForUser($request->user(), $validated['name']);

        return redirect()
            ->route('owner.settings.index')
            ->with('status', 'Token API generado correctamente.')
            ->with('api_token_plaintext', $plainTextToken)
            ->with('api_token_name', $token->name)
            ->with('api_token_action', 'created');
    }

    public function resetApiTokens(Request $request)
    {
        try {
            $organization = $this->ensureOrganization($request);
        } catch (ValidationException $e) {
            return redirect()
                ->route('owner.settings.index')
                ->withErrors(['api_token' => $e->errors()['organization'][0] ?? 'No se pudo validar la organización.']);
        }

        $validated = $request->validate([
            'name' => ['required', 'string', 'max:120'],
        ]);

        $user = $request->user();
        $user->apiTokens()
            ->whereNull('revoked_at')
            ->update(['revoked_at' => now()]);

        [$token, $plainTextToken] = ApiToken::issueForUser($user, $validated['name']);

        return redirect()
            ->route('owner.settings.index')
            ->with('status', 'Token API restablecido correctamente. Los tokens anteriores quedaron revocados.')
            ->with('api_token_plaintext', $plainTextToken)
            ->with('api_token_name', $token->name)
            ->with('api_token_action', 'reset');
    }

    public function revokeApiToken(Request $request, ApiToken $apiToken)
    {
        $user = $request->user();

        if (
            (int) $apiToken->user_id !== (int) $user->id
            || (int) $apiToken->organization_id !== (int) ($user->organization_id ?? 0)
        ) {
            abort(404);
        }

        if ($apiToken->revoked_at === null) {
            $apiToken->forceFill(['revoked_at' => now()])->save();
        }

        return redirect()
            ->route('owner.settings.index')
            ->with('status', 'Token API revocado correctamente.');
    }
}
