<?php

namespace App\Services;

use App\Models\Role;
use App\Models\RoleUser;
use App\Models\User;
use App\Models\UserComunity;
use App\Models\UserDirectorData;
use App\Models\UserPersonType;
use App\Models\UserUgel;
use App\Repositories\PersonTypeRepository;
use App\Repositories\UserRepository;
use Config\Database;
use Exception;

class UserService {

    protected PersonTypeRepository $personTypeRepository;
    protected UserRepository $userRepository;

    public function __construct() {
        $this->personTypeRepository = new PersonTypeRepository();
        $this->userRepository = new UserRepository();
    }

    public function getUserRoles($userId)
    {
        return $this->userRepository->getUserRoles($userId);
    }

    public function createComunityUser($data)
    {
        $db = Database::getConnection();
        $db->beginTransaction();

        try {
            $documento = trim($data['dni']); // Puede ser DNI o RUC
            $comunityUser = null;

            // Detectar si es RUC (11 dígitos) o DNI (8 dígitos)
            if (strlen($documento) === 11) {
                $comunityUser = UserComunity::findBy('ruc', $documento);
            } elseif (strlen($documento) === 8) {
                $comunityUser = UserComunity::findBy('dni', $documento);
            } else {
                throw new Exception("El número de documento ingresado no es válido (debe tener 8 o 11 dígitos).");
            }

            $userId = null;

            if ($comunityUser) {
                if ($comunityUser->user_id) {
                    throw new Exception("El usuario ya está registrado en el sistema.");
                }
            } else {
                // Si no existe en user_comunity, se crea un nuevo registro
                $comunityUser = new UserComunity();
            }

            // Crear usuario del sistema
            $user = new User();
            $user->username = $data['username'];
            $user->password = password_hash($data['password'], PASSWORD_BCRYPT);
            $user->role = 'COMUNITY';
            $userId = $user->save();

            if (!$userId) {
                throw new Exception("Error al guardar las credenciales del usuario.");
            }

            // Asignar datos personales o empresariales
            $comunityUser->name = $data['name'] ?? null;
            $comunityUser->paternal_surname = $data['paternal_surname'] ?? null;
            $comunityUser->maternal_surname = $data['maternal_surname'] ?? null;

            // Asignar correctamente DNI o RUC según el valor recibido
            if (strlen($documento) === 11) {
                $comunityUser->ruc = $documento;
                $comunityUser->dni = null;
            } else {
                $comunityUser->dni = $documento;
                $comunityUser->ruc = null;
            }

            $comunityUser->company_name = !empty($data['company_name']) ? $data['company_name'] : null;
            $comunityUser->phone = !empty($data['phone']) ? $data['phone'] : null;
            $comunityUser->email = !empty($data['email']) ? $data['email'] : null;
            $comunityUser->address = !empty($data['address']) ? $data['address'] : null;
            $comunityUser->user_id = $userId;
            $comunityUser->active = 1;
            $comunityUser->save();

            // Asignar rol COMUNITY
            $roleComunity = Role::findBy('name', 'COMUNITY');

            if ($roleComunity) {
                $roleUserComunity = new RoleUser();
                $roleUserComunity->user_id = $userId;
                $roleUserComunity->role_id = $roleComunity->id;
                $roleUserComunity->save();
            }

            // Guardar tipos de persona
            if (!empty($data['person_types'])) {
                foreach ($data['person_types'] as $personTypeId) {
                    $userPersonType = new UserPersonType();
                    $userPersonType->comunity_user_id = $comunityUser->id;
                    $userPersonType->person_type_id = $personTypeId;
                    $userPersonType->active = 1;
                    $userPersonType->save();
                }

                // Registrar datos adicionales si es DIRECTOR
                $directorType = $this->personTypeRepository->findByDescription('DIRECTOR');
                if ($directorType && in_array($directorType->id, $data['person_types'])) {
                    if (empty($data['school_name'])) {
                        throw new Exception("Debe ingresar el nombre del colegio para el tipo de persona DIRECTOR.");
                    }

                    $directorData = new UserDirectorData([
                        'comunity_user_id' => $comunityUser->id,
                        'school_name' => $data['school_name']
                    ]);
                    $directorData->save();
                }

            } else {
                throw new Exception("Debe seleccionar al menos un tipo de persona.");
            }

            $db->commit();
            return $comunityUser;
        } catch (Exception $e) {
            $db->rollBack();
            throw new Exception($e->getMessage());
        }
    }



    // public function createComunityUser($data) {
    //     $db = Database::getConnection();
    //     $db->beginTransaction();

    //     try {
    //         $comunityUser = UserComunity::findBy('dni', $data['dni']);
    //         $userId = null;

    //         if ($comunityUser) {
    //             if ($comunityUser->user_id) {
    //                 throw new Exception("El usuario ya está registrado en el sistema.");
    //             }
    //         } else {
    //             // Si no existe en user_comunity, se crea un nuevo registro
    //             $comunityUser = new UserComunity();
    //         }

    //         $user = new User();
    //         $user->username = $data['username'];
    //         $user->password = password_hash($data['password'], PASSWORD_BCRYPT);
    //         $user->role = 'COMUNITY';
    //         $userId = $user->save();

    //         if (!$userId) {
    //             throw new Exception("Error al guardar las credenciales del usuario.");
    //         }

    //         // Actualizar datos personales en UserComunity y asignar user_id
    //         $comunityUser->name = $data['name'];
    //         $comunityUser->paternal_surname = $data['paternal_surname'];
    //         $comunityUser->maternal_surname = $data['maternal_surname'];
    //         $comunityUser->dni = $data['dni'];
    //         $comunityUser->company_name = isset($data['company_name']) && trim($data['company_name']) !== '' ? $data['company_name'] : null;
    //         $comunityUser->ruc = isset($data['ruc']) && trim($data['ruc']) !== '' ? $data['ruc'] : null;
    //         $comunityUser->phone = isset($data['phone']) && trim($data['phone']) !== '' ? $data['phone'] : null;
    //         $comunityUser->email = isset($data['email']) && trim($data['email']) !== '' ? $data['email'] : null;
    //         $comunityUser->address = isset($data['address']) && trim($data['address']) !== '' ? $data['address'] : null;
    //         $comunityUser->user_id = $userId;
    //         $comunityUser->active = 1;
    //         $comunityUser->save();

    //         $roleComunity = Role::findBy('name', 'COMUNITY');

    //         if ($roleComunity) {
    //             $roleUserComunity = new RoleUser();
    //             $roleUserComunity->user_id = $userId;
    //             $roleUserComunity->role_id = $roleComunity->id;
    //             $roleUserComunity->save();
    //         }

    //         if (!empty($data['person_types'])) {
    //             foreach ($data['person_types'] as $personTypeId) {
    //                 $userPersonType = new UserPersonType();
    //                 $userPersonType->comunity_user_id = $comunityUser->id;
    //                 $userPersonType->person_type_id = $personTypeId;
    //                 $userPersonType->active = 1;
    //                 $userPersonType->save();
    //             }

    //         // Registrar datos adicionales si es DIRECTOR
    //         $directorType = $this->personTypeRepository->findByDescription('DIRECTOR');
    //         if (in_array($directorType->id, $data['person_types'])) {
    //             if (empty($data['school_name'])) {
    //                 throw new Exception("Debe ingresar el nombre del colegio para el tipo de persona DIRECTOR.");
    //             }

    //             $directorData = new UserDirectorData([
    //                 'comunity_user_id' => $comunityUser->id,
    //                 'school_name' => $data['school_name']
    //             ]);
    //             $directorData->save();
    //         }

    //         } else {
    //             throw new Exception("Debe seleccionar al menos un tipo de persona.");
    //         }

    //         $db->commit();
    //         return $comunityUser;
    //     } catch (Exception $e) {
    //         $db->rollBack();
    //         throw new Exception($e->getMessage());
    //     }
    // }

    public static function getUser ()
    {
        $user = User::find($_SESSION['user_id']);

        if($_SESSION['role'] !== 'COMUNITY') {
            $actualUser = UserUgel::findBy('user_id', $user->id);
        } 
        else {
            $actualUser = UserComunity::findBy('user_id', $user->id);
        }

        return $actualUser;
    }

    public static function getLoggedUser()
    {
        return User::find($_SESSION['user_id']);
    }

    public function findByUsername($username)
    {
        return $this->userRepository->findByUsername($username);
    }


    // public function verifyPassword($password)
    // {
    //     return password_verify($password, $this->password);
    // }

    public function updateProfilePicture($fileName, $user)
    {
        return $this->userRepository->updateProfilePicture($fileName, $user);
    }

    public function findComunityUserByDni($dni)
    {
        return $this->userRepository->findComunityUserByDni($dni);
    }

    public function findComunityUserByRuc($ruc)
    {
        return $this->userRepository->findComunityUserByRuc($ruc);
    }

    public function searchComunityUsersByName(string $q, int $limit = 20): array
    {
        return $this->userRepository->searchComunityUsersByName($q, $limit);
    }

    public function searchComunityByDocument(string $q, int $limit = 5): array
    {
        return $this->userRepository->searchComunityByDocument($q, $limit);
    }

    public function findComunityUserForPasswordRecovery($dni, $email, $ruc = null)
    {
        $this->userRepository->findComunityUserForPasswordRecovery($dni, $email, $ruc);
    }

    public function getAllUsersUgel()
    {
        return $this->userRepository->getAllUsersUgel();
    }

    public function findUserUgelForPasswordRecovery($dni, $email)
    {
        $this->userRepository->findUserUgelForPasswordRecovery($dni, $email);
    }

    public function findMirrorComunity($dni)
    {
        return UserComunity::findBy('dni', $dni);
    }

    public function createMirrorComunity($ugelUser)
    {
        $mirrorComunity = new UserComunity();
        $mirrorComunity->name = $ugelUser->name;
        $mirrorComunity->paternal_surname = $ugelUser->paternal_surname;
        $mirrorComunity->maternal_surname = $ugelUser->maternal_surname;
        $mirrorComunity->dni = $ugelUser->dni;
        $mirrorComunity->phone = $ugelUser->phone;
        $mirrorComunity->email = $ugelUser->email;
        $mirrorComunity->address = $ugelUser->address;
        $mirrorComunity->user_id = $ugelUser->user_id;
        $mirrorComunity->active = $ugelUser->active;
        $mirrorComunity->save();

        $userPersonType = new UserPersonType();
        $userPersonType->comunity_user_id = $mirrorComunity->id;
        $userPersonType->person_type_id = $this->personTypeRepository->findByDescription('NATURAL')->id;
        $userPersonType->active = 1;
        $userPersonType->save();

        return $mirrorComunity;
    }

    public static function syncMirrorData($user, $currentRole, $data)
    {
        // Determinar modelo espejo según rol
        if ($currentRole === 'UGEL') {
            $mirror = UserComunity::findBy('dni', $user->dni);
        } elseif ($currentRole === 'COMUNITY') {
            $mirror = UserUgel::findBy('dni', $user->dni);
        } else {
            return; // No aplica para otros roles
        }

        if (!$mirror) return;

        // 🔹 Obtener las propiedades definidas en el modelo espejo
        $mirrorProps = array_keys(get_object_vars($mirror));

        // 🔹 Asignar solo los campos que existan en el espejo
        foreach ($data as $field => $value) {
            if (in_array($field, $mirrorProps)) {
                $mirror->$field = $value;
            }
        }

        $mirror->save();
    }

}

