<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Models\Sucursal;
use App\Models\User;
use App\Support\TenantContext;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class TenantSelectionController extends Controller
{
    public function __construct(private readonly TenantContext $tenantContext)
    {
    }

    public function create(Request $request): View|RedirectResponse
    {
        /** @var User|null $user */
        $user = $request->user();

        if (! $user) {
            return redirect()->route('login');
        }

        $empresaIds = $user->accessibleEmpresaIds();
        if ($empresaIds === []) {
            abort(403, 'No tienes empresas disponibles para seleccionar.');
        }

        $empresas = $user->empresas()
            ->whereIn('empresas.id', $empresaIds)
            ->with([
                'sucursales' => static fn ($query) => $query
                    ->where('activa', 1)
                    ->orderBy('nombre'),
            ])
            ->orderBy('empresas.nombre')
            ->get();

        if ($user->empresa && ! $empresas->contains('id', $user->empresa->id)) {
            $empresaPrincipal = $user->empresa()
                ->with([
                    'sucursales' => static fn ($query) => $query
                        ->where('activa', 1)
                        ->orderBy('nombre'),
                ])
                ->first();

            if ($empresaPrincipal) {
                $empresas->push($empresaPrincipal);
            }
        }

        $empresas = $empresas->unique('id')->values();
        $hasMultipleEmpresas = $empresas->count() > 1;
        $hasMultipleSucursales = $empresas->contains(
            static fn ($empresa): bool => $empresa->sucursales->count() > 1
        );

        if (! $hasMultipleEmpresas && ! $hasMultipleSucursales) {
            return redirect()->route('dashboard');
        }

        $currentEmpresaId = $this->tenantContext->empresaId();
        if (! $currentEmpresaId && $empresas->count() === 1) {
            $currentEmpresaId = (int) $empresas->first()->id;
        }

        $currentEmpresa = $currentEmpresaId ? $empresas->firstWhere('id', $currentEmpresaId) : null;
        $currentSucursalId = $this->tenantContext->sucursalId();
        if (
            $currentEmpresa
            && $currentSucursalId
            && ! $currentEmpresa->sucursales->contains('id', $currentSucursalId)
        ) {
            $currentSucursalId = null;
        }

        if (
            ! $currentSucursalId
            && $currentEmpresa
            && $user->sucursal_id
            && $currentEmpresa->sucursales->contains('id', (int) $user->sucursal_id)
        ) {
            $currentSucursalId = (int) $user->sucursal_id;
        }

        return view('auth.tenant-select', [
            'empresas' => $empresas,
            'currentEmpresaId' => $currentEmpresaId,
            'currentSucursalId' => $currentSucursalId,
            'canSelectEmpresa' => $hasMultipleEmpresas,
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        /** @var User|null $user */
        $user = $request->user();

        if (! $user) {
            return redirect()->route('login');
        }

        $empresaId = (int) $request->validate([
            'empresa_id' => ['required', 'integer'],
            'sucursal_id' => ['nullable', 'integer'],
        ])['empresa_id'];

        if (! $user->belongsToEmpresa($empresaId)) {
            throw ValidationException::withMessages([
                'empresa_id' => 'No tienes acceso a la empresa seleccionada.',
            ]);
        }

        $sucursalId = $request->filled('sucursal_id') ? (int) $request->input('sucursal_id') : null;

        if (
            $sucursalId
            && ! Sucursal::query()
                ->whereKey($sucursalId)
                ->where('empresa_id', $empresaId)
                ->where('activa', 1)
                ->exists()
        ) {
            throw ValidationException::withMessages([
                'sucursal_id' => 'La sucursal seleccionada no pertenece a la empresa o esta inactiva.',
            ]);
        }

        if (! $sucursalId) {
            $sucursalId = Sucursal::query()
                ->where('empresa_id', $empresaId)
                ->where('activa', 1)
                ->orderBy('id')
                ->value('id');
        }

        $this->tenantContext->setEmpresaId($empresaId);
        $this->tenantContext->setSucursalId($sucursalId ? (int) $sucursalId : null);

        $status = $sucursalId
            ? 'Contexto de empresa/sucursal actualizado.'
            : 'Contexto de empresa actualizado. No hay sucursales activas disponibles.';

        return redirect()->route('dashboard')
            ->with('status', $status);
    }
}
