<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\UserProfile;
use App\Models\RoleUser;
use App\Models\Role;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use App\Exceptions\GlobalException;
use Illuminate\Support\Facades\Auth;
use Throwable;
use App\Models\Especiality;
use App\Models\UserProfileHasEspeciality;

use \Exception;
use DateTime;


class UserController extends Controller
{
    
     /**
     * Muestra la vista de doctores.
     */
    public function viewDoctors(Request $request){
        try{
             $doctors = User::getAllDoctors();
             return view("view-doctors", ['data' => $doctors]);
        }catch (Throwable $th) {
             throw new GlobalException($th->getMessage());
         }
     }

    /**
     * Muestra la vista de usuarios.
     */
    public function view(Request $request)
    {
        try {
            $data = $request->all();
            return view("view-users", [
                "model" => $data
            ]);
        } catch (Throwable $th) {
            throw new GlobalException($th->getMessage());
        }
    }

   /**
 * Crea un nuevo usuario, asigna su rol y crea el perfil asociado
 * validando los campos de perfil y especialidades solo si vienen en el request.
 */
public function create(Request $request)
{
    try {
        // Si el método no es POST, mostramos la vista para crear usuario
        if (!$request->isMethod('post')) {
            $user = new User();
            $especialities = Especiality::getEspecialities();
            $userProfile = new UserProfile();
            return view("create-user", compact('user', 'userProfile', 'especialities'));
        }

        $data = $request->all();
        $messages = [
            'email.unique' => __("common.email-unique"),
            // Puedes agregar más mensajes personalizados aquí...
        ];

        // Reglas de validación para el usuario (obligatorios siempre)
        $rules = [
            'name'           => 'required|string',
            'email'          => 'required|email|unique:users,email',
            'password'       => 'required|string|min:6',
            'passwordRepeat' => 'required|same:password',
            'role'           => 'required|string',
        ];

        // Reglas para el perfil: si vienen en el request se validan como requeridos
        $profileRules = [
            'firstname'      => 'sometimes|required|string',
            'lastname'       => 'sometimes|required|string',
            'birthday'       => 'sometimes|required|string',
            'gender'         => 'sometimes|required|string|in:F,M,O',
            'phone'          => 'sometimes|required|string',
            'address'        => 'sometimes|required|string',
            'age'            => 'sometimes|required|string',
        ];


        // Reglas para especialidades si se incluyen
        $especialitiesRules = [
            'especialities_selected'   => 'sometimes|required|string',
        ];


        $rules = array_merge($rules, $profileRules, $especialitiesRules);

        $validator = Validator::make($data, $rules, $messages);
        if ($validator->fails()) {
            // Redirige al formulario con los errores y los datos viejos
            return redirect()
                ->back()
                ->withErrors($validator)
                ->withInput();
        }

        // Verificación adicional: Solo un usuario admin puede crear un usuario con nombre "admin"
        if (trim($data["name"]) === "admin" && !Auth::user()->hasRole(['admin', 'root'])) {
            throw new GlobalException(__("not-authorized.message"));
        }

        // Obtenemos el role_id a partir de la clave de rol
        $roleName = config("app.roles")[$data["role"]];
        $role = Role::where("name", $roleName)->first();
        if (!$role) {
            throw new GlobalException(__("Role not found"));
        }
        $roleId = $role->id;

        DB::beginTransaction();

        // Creamos el usuario
        $user = new User();
        $user->name = $data["name"];
        $user->email = $data["email"];
        $user->password = Hash::make($data["password"]);
        $user->save();

        // Asignamos el rol al usuario
        RoleUser::create([
            'role_id'   => $roleId,
            'user_id'   => $user->id,
            'user_type' => 'App\Models\User',
        ]);

        // Formateo de fecha de cumpleaños
        $birthday = null;
        if (isset($data['birthday'])) {
            $birthday = date_create_from_format('d/m/Y', $data['birthday']) ?? null;
        }

        // Si vienen campos del perfil, lo creamos
        if ($request->hasAny(['firstname', 'lastname', 'birthday', 'gender', 'phone', 'address'])) {
            $userProfile = new UserProfile();
            $userProfile->id        = md5(uniqid($user->id));
            $userProfile->users_id  = $user->id;
            $userProfile->firstname = $data['firstname'] ?? null;
            $userProfile->lastname  = $data['lastname'] ?? null;
            $userProfile->age       = $data['age'] ?? null;
            $userProfile->email     = $data['email'];
            $userProfile->birthday  = $birthday ?? null;
            $userProfile->gender    = $data['gender'] ?? null;
            $userProfile->phone     = $data['phone'] ?? null;
            $userProfile->address   = $data['address'] ?? null;
            $userProfile->save();

            // Guardar especialidades si vienen
            if (isset($data['especialities_selected'])) {
                $especialitiesSelected = explode(",",$data['especialities_selected']);
                foreach ( $especialitiesSelected as $especialityId) {
                    UserProfileHasEspeciality::create([
                        'user_profile_id' => $userProfile->id,
                        'especiality_id'  => $especialityId,
                    ]);
                }
            }
            DB::commit();

            return redirect()->route("/admin/view-doctors");
        }else{
            DB::commit();
            return redirect()->route("/admin/view-users");
        }

       
    } catch (Throwable $th) {
        DB::rollBack();
        throw new GlobalException($th->getMessage());
    }
}



public function updateDoctor(Request $request)
{
    $data = $request->all();

    $id = $data["id"];
    try {
        // Si no es POST, mostramos el formulario de edición
        if (!$request->isMethod('post')) {
            $userProfile = UserProfile::with(['user', 'especialities'])->where('users_id', $id)->first();
            $date = new DateTime($userProfile->birthday);
            $userProfile->birthday = $date->format("d/m/Y");
            $user = $userProfile->user;
            $especialities = Especiality::getEspecialities();
            $selectedEspecialities = $userProfile->especialities->pluck('id')->toArray();

            return view('update-doctor', compact('user', 'userProfile', 'especialities', 'selectedEspecialities'));
        }

        // Datos del request
        $data = $request->all();

        $messages = [
            'email.unique' => __("common.email-unique"),
            // Puedes agregar más mensajes personalizados aquí...
        ];


        // Validaciones
        $rules = [
            'email'     => 'required|email|unique:user_profile,email,' . $id,
            'firstname' => 'required|string',
            'lastname'  => 'required|string',
            'birthday'  => 'nullable|string',
            'gender'    => 'nullable|in:F,M,O',
            'phone'     => 'nullable|string',
            'address'   => 'nullable|string',
            'age'       => 'nullable|string',
            'especialities_selected'   => 'sometimes|required|string',
        ];


        $validator = Validator::make($data, $rules, $messages);
        if ($validator->fails()) {
            // Redirige al formulario con los errores y los datos viejos
            return redirect()
                ->back()
                ->withErrors($validator)
                ->withInput();
        }

        DB::beginTransaction();

        // Buscar perfil y usuario
        $userProfile = UserProfile::with('user')->findOrFail($id);
        $user = $userProfile->user;

        // Actualizar usuario
        $user->email = $data['email'];
        $user->save();

        // Parsear fecha
        $birthday = null;
        if (!empty($data['birthday'])) {
            $birthday = date_create_from_format('d/m/Y', $data['birthday']) ?: null;
        }

        // Actualizar perfil
        $userProfile->firstname = $data['firstname'];
        $userProfile->lastname  = $data['lastname'];
        $userProfile->age       = $data['age'] ?? null;
        $userProfile->birthday  = $birthday;
        $userProfile->gender    = $data['gender'] ?? null;
        $userProfile->phone     = $data['phone'] ?? null;
        $userProfile->email     = $data['email'] ?? null;

        $userProfile->address   = $data['address'] ?? null;
        $userProfile->save();

        if (isset($data['especialities_selected'])) {
            // Convertir el string en un arreglo
            $especialities = explode(',', $data['especialities_selected']);
            // Sincronizar las especialidades
            $userProfile->especialities()->sync($especialities);
        }
        

        DB::commit();

        return redirect()->route('/admin/view-doctors')->with('success', __('Doctor updated successfully'));
    } catch (Throwable $th) {
        DB::rollBack();
        throw new GlobalException($th->getMessage());
    }
}


}
