import { canNavigate } from '@layouts/plugins/casl';
import { useCookieStore } from '@layouts/stores/config';
import { useAlert } from '@/composables/useAlert';
import { socket } from "@/composables/useSocket";

const { alert, setAlert } = useAlert();

const checarNextQuery = (to) => {
  if (to.fullPath.includes('login') || to.fullPath.includes('register')
    || to.fullPath.includes('senha') || to.fullPath.includes('seja')) {
    return false
  }

  return true
}

export const setupGuards = router => {
  router.beforeEach(async (to, from, next) => {
    const token = useCookie('accessToken').value;
    const usuario = useCookie('userData').value;
    const roleInit = usuario?.role;

    if (to.meta.public || to.meta.unauthenticatedOnly) {
      if (token && usuario && usuario.id) {
        const res = await authenticateUser(usuario.id, token, roleInit, next, to);
        if (res) {
          next();
        }
      } else {
        next();
      }
      return;
    }

    if (!token && !['login', 'register', 'forgot-password', 'reset-password'].includes(to.name)) {
      console.log('Não há token');
      next({ name: 'login', query: checarNextQuery(to) ? { to: to.fullPath } : {} });
      return;
    } else if (!token) {
      console.log('Não há token para rotas públicas');
      next();
      return;
    } else if (canNavigate(to)) {
      if (!usuario || !usuario.id) {
        console.log('Sem usuário');
        next({ name: 'login', query: checarNextQuery(to) ? { to: to.fullPath } : {} });
        return;
      }

      const res = await authenticateUser(usuario.id, token, roleInit, next, to);
      if (res) {
        next();
      }
    } else {
      console.log('Sem permissão');
      setAlert('Você não tem permissão para acessar essa página.', 'error', 'tabler-lock-access-off', 3000);
      next({ name: 'login', query: checarNextQuery(to) ? { to: to.fullPath } : {} });
    }
  });
};

async function authenticateUser(id, token, roleInit, next, to) {
  try {
    const res = await $api('/conta/auth-cookie', {
      method: 'POST',
      body: {
        id: id,
        token: token,
        roleInit: roleInit,
      },
    });

    console.log('Auth Success: ', res.response);

    const { accessToken, userData, userAbilityRules, maxAge } = res.response;
    const tokenValue = accessToken || token;
    const maxAgeValue = maxAge || 30 * 24 * 60 * 60;

    const cookieStore = useCookieStore();
    cookieStore.updateCookies({
      userData: userData,
      rules: userAbilityRules,
      accessToken: tokenValue,
      maxAge: maxAgeValue,
    });

    socket.emit('changePage', { page: to.name, id_user: userData.id });

    return true;
  } catch (error) {
    console.error('Auth Error: ', error, error.response);
    handleAuthError(error, next);
    return false;
  }
}

function handleAuthError(error, next) {
  if (error.response) {
    if (error.response.status === 401) {
      setAlert('Login expirado. Faça login novamente.', 'error', 'tabler-alert-triangle', 3000);
    } else {
      setAlert('Ocorreu um erro com seu acesso. Faça login novamente.', 'error', 'tabler-alert-triangle', 3000);
    }
    clearAuthCookies();
    next({ name: 'login' });
  } else {
    setAlert('Ocorreu um erro com seu acesso. Faça login novamente.', 'error', 'tabler-alert-triangle', 3000);
    clearAuthCookies();
    next({ name: 'login' });
  }
}

function clearAuthCookies() {
  useCookie('userAbilityRules').value = null;
  useCookie('userData').value = null;
  useCookie('accessToken').value = null;
}
