<?php

namespace App\Http\Controllers\Coach;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Setting;
use App\Models\User;
use App\Notifications\AdminNewClientCreated;
use App\Notifications\ClientPortalActivated;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;

class ClientController extends Controller
{
    /**
     * Display a listing of clients.
     */
    public function index(Request $request): Response
    {
        $query = $request->user()->clients();

        // Search
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('email', 'like', "%{$search}%");
            });
        }

        // Filter by status
        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        }

        $clients = $query->withCount(['workouts', 'mealPlans'])
            ->with('portalUser:id,avatar')
            ->latest()
            ->paginate(12)
            ->withQueryString();

        // Add macros and avatar_url to each client
        $clients->getCollection()->transform(function ($client) {
            $client->macros = $client->calculateMacros();
            $avatar = $client->portalUser?->avatar;
            if ($avatar) {
                $client->avatar_url = str_starts_with($avatar, 'http') || str_starts_with($avatar, '/storage/') 
                    ? $avatar 
                    : '/storage/' . $avatar;
            } else {
                $client->avatar_url = null;
            }
            return $client;
        });

        return Inertia::render('Coach/Clients/Index', [
            'clients' => $clients,
            'filters' => $request->only(['search', 'status']),
            'canCreate' => $request->user()->canCreate('clients'),
            'remaining' => $request->user()->remaining('clients'),
        ]);
    }

    /**
     * Show the form for creating a new client.
     */
    public function create(Request $request): Response
    {
        if (!$request->user()->canCreate('clients')) {
            return Inertia::render('Coach/LimitReached', [
                'resource' => 'clientes',
            ]);
        }

        return Inertia::render('Coach/Clients/Create');
    }

    /**
     * Store a newly created client.
     */
    public function store(Request $request): RedirectResponse
    {
        if (!$request->user()->canCreate('clients')) {
            return back()->with('error', 'Has alcanzado el límite de clientes de tu plan.');
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:20',
            'age' => 'nullable|integer|min:10|max:100',
            'weight' => 'nullable|numeric|min:30|max:300',
            'height' => 'nullable|numeric|min:100|max:250',
            'gender' => 'nullable|in:male,female',
            'objective' => 'nullable|in:lose,maintain,gain',
            'activity_level' => 'nullable|in:sedentary,light,moderate,active,very_active',
            'calorie_adjustment' => 'nullable|integer|min:-100|max:100',
            'notes' => 'nullable|string|max:1000',
        ]);

        $client = $request->user()->clients()->create($validated);

        // Calculate BMR, TDEE and BMI if we have enough data
        if ($client->weight && $client->height && $client->age && $client->gender) {
            $client->updateMetrics();
        }

        // Notify admins about new client creation
        if (Setting::get('notify_new_client', true)) {
            $admins = User::where('role', 'admin')->where('status', 'active')->get();
            foreach ($admins as $admin) {
                $admin->notify(new AdminNewClientCreated($client, $request->user()));
            }
        }

        return redirect()->route('coach.clients.show', $client)
            ->with('success', 'Cliente creado correctamente.');
    }

    /**
     * Display the specified client.
     */
    public function show(Request $request, Client $client): Response
    {
        $this->authorize('view', $client);

        $client->load(['workouts.exercises', 'mealPlans.dietPlans.items.food', 'complianceLogs', 'progressPhotos', 'portalUser']);
        
        // Format avatar path (prioritize portalUser avatar if client has portal access)
        $avatar = $client->avatar;
        if ($client->portalUser && $client->portalUser->avatar) {
            $avatar = $client->portalUser->avatar;
        }

        if ($avatar) {
            $client->avatar = str_starts_with($avatar, 'http') || str_starts_with($avatar, '/storage/') 
                ? $avatar 
                : '/storage/' . $avatar;
        }

        return Inertia::render('Coach/Clients/Show', [
            'client' => $client,
        ]);
    }

    /**
     * Show the form for editing the specified client.
     */
    public function edit(Request $request, Client $client): Response
    {
        $this->authorize('update', $client);

        return Inertia::render('Coach/Clients/Edit', [
            'client' => $client,
        ]);
    }

    /**
     * Update the specified client.
     */
    public function update(Request $request, Client $client): RedirectResponse
    {
        $this->authorize('update', $client);

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:20',
            'age' => 'nullable|integer|min:10|max:100',
            'weight' => 'nullable|numeric|min:30|max:300',
            'height' => 'nullable|numeric|min:100|max:250',
            'gender' => 'nullable|in:male,female',
            'objective' => 'nullable|in:lose,maintain,gain',
            'activity_level' => 'nullable|in:sedentary,light,moderate,active,very_active',
            'calorie_adjustment' => 'nullable|integer|min:-100|max:100',
            'notes' => 'nullable|string|max:1000',
            'is_active' => 'boolean',
        ]);

        $client->update($validated);

        // Recalculate metabolism if physical data changed
        if ($client->wasChanged(['weight', 'height', 'age', 'gender', 'activity_level'])) {
            $client->updateMetrics();
        }

        return back()->with('success', 'Cliente actualizado correctamente.');
    }

    /**
     * Remove the specified client.
     */
    public function destroy(Request $request, Client $client): RedirectResponse
    {
        $this->authorize('delete', $client);

        $client->delete();

        return redirect()->route('coach.clients.index')
            ->with('success', 'Cliente eliminado correctamente.');
    }

    /**
     * Toggle client active status.
     */
    public function toggleActive(Request $request, Client $client): RedirectResponse
    {
        $this->authorize('update', $client);

        $client->update(['is_active' => !$client->is_active]);

        $status = $client->is_active ? 'activado' : 'desactivado';
        return back()->with('success', "Cliente {$status}.");
    }

    /**
     * Activate client portal and send credentials via email.
     */
    public function activatePortal(Request $request, Client $client): RedirectResponse
    {
        $this->authorize('update', $client);

        // Validate client has email
        if (!$client->email) {
            return back()->with('error', 'El cliente debe tener un email para activar el portal.');
        }

        $coach = $request->user();
        $sendEmail = $request->boolean('send_email', true);

        // Generate random password
        $password = Str::random(10);

        // Check if user already exists
        $user = User::where('email', $client->email)->first();

        if ($user) {
            // Link existing user to this client
            if ($user->role !== 'client') {
                return back()->with('error', 'Este email ya está registrado con otro rol.');
            }
            
            // Update client link - use client_user_id (portal user), not user_id (coach)
            $client->client_user_id = $user->id;
            $client->portal_active = true;
            $client->save();

            return back()->with('success', 'El cliente ya tiene una cuenta. Portal activado.');
        }

        // Create new user for client
        $user = User::create([
            'name' => $client->name,
            'email' => $client->email,
            'password' => Hash::make($password),
            'role' => 'client',
            'status' => 'active',
            'email_verified_at' => now(),
        ]);

        // Link user to client - use client_user_id (portal user), not user_id (coach)
        $client->client_user_id = $user->id;
        $client->portal_active = true;
        $client->save();

        // Send email with credentials
        if ($sendEmail) {
            $user->notify(new ClientPortalActivated($client, $password, $coach->name));
        }

        $message = $sendEmail 
            ? 'Portal activado. Se han enviado las credenciales por email.'
            : "Portal activado. Credenciales: Email: {$client->email} | Contraseña: {$password}";

        return back()->with('success', $message);
    }

    /**
     * Resend portal credentials to client.
     */
    public function resendCredentials(Request $request, Client $client): RedirectResponse
    {
        $this->authorize('update', $client);

        if (!$client->user) {
            return back()->with('error', 'El cliente no tiene portal activado.');
        }

        $coach = $request->user();
        
        // Generate new password
        $password = Str::random(10);
        $client->user->update(['password' => Hash::make($password)]);

        // Send email
        $client->user->notify(new ClientPortalActivated($client, $password, $coach->name));

        return back()->with('success', 'Nuevas credenciales enviadas por email.');
    }
}
