<template>
  <q-layout view="lHh Lpr lFf" class="app-shell">
    <q-header v-if="!isLoginPage" class="app-header">
      <q-toolbar class="app-toolbar">
        <div class="app-toolbar__page">
          <q-btn
            flat
            dense
            round
            icon="sym_o_menu"
            class="app-toolbar__menu"
            aria-label="Abrir menu"
            @click="toggleLeftDrawer"
          />

          <div class="app-toolbar__breadcrumbs">
            <span class="app-toolbar__eyebrow">Clipper · Painel</span>
            <h1 class="app-toolbar__title">{{ currentRouteTitle }}</h1>
            <p v-if="currentRouteDescription" class="app-toolbar__subtitle">
              {{ currentRouteDescription }}
            </p>
          </div>
        </div>

        <div class="app-toolbar__actions">
          <Button
            v-if="quickAction"
            :icon="quickAction.icon || 'sym_o_add'"
            :label="quickAction.label"
            @click="handleQuickAction"
          />

          <q-btn
            flat
            round
            dense
            color="primary"
            icon="sym_o_notifications"
            class="app-toolbar__icon"
            aria-label="Notificações"
          />

          <Toggle v-model="darkMode" color="primary" @toggle="toggleDarkMode" />

          <q-btn
            v-if="!isLoginPage"
            flat
            dense
            round
            class="app-toolbar__avatar-btn"
          >
            <q-avatar size="36px" class="app-toolbar__avatar">
              <span>{{ userInitials }}</span>
            </q-avatar>

            <q-menu
              class="app-user-menu"
              anchor="bottom right"
              self="top right"
            >
              <div class="app-user-menu__header">
                <q-avatar size="40px" color="primary" text-color="white">
                  {{ userInitials }}
                </q-avatar>

                <div class="app-user-menu__info">
                  <div class="app-user-menu__name">
                    {{ currentUserName || "Usuário" }}
                  </div>
                  <div
                    v-if="
                      currentUserEmail && currentUserEmail !== currentUserName
                    "
                    class="app-user-menu__email"
                  >
                    {{ currentUserEmail }}
                  </div>
                </div>
              </div>

              <q-separator spaced />

              <q-list padding class="app-user-menu__list">
                <q-item clickable disable>
                  <q-item-section avatar>
                    <q-icon name="sym_o_settings" />
                  </q-item-section>
                  <q-item-section>
                    <q-item-label>Configurações</q-item-label>
                    <q-item-label caption>Em breve</q-item-label>
                  </q-item-section>
                </q-item>

                <q-item
                  clickable
                  :disable="logoutLoading"
                  @click="handleLogout"
                >
                  <q-item-section avatar>
                    <q-icon name="sym_o_logout" />
                  </q-item-section>
                  <q-item-section>
                    <q-item-label>Logout</q-item-label>
                  </q-item-section>
                </q-item>
              </q-list>
            </q-menu>
          </q-btn>
        </div>
      </q-toolbar>
    </q-header>

    <q-drawer
      v-if="!isLoginPage"
      v-model="leftDrawerOpen"
      show-if-above
      :width="260"
      bordered
      class="app-drawer"
    >
      <div class="app-drawer__header">
        <q-avatar size="44px" color="primary" text-color="white">CI</q-avatar>
        <div>
          <div class="app-drawer__brand">Clipper IA</div>
          <div class="app-drawer__tag">Assistente de cortes</div>
        </div>
      </div>

      <q-scroll-area class="fit">
        <template v-if="menuSections.length">
          <q-list padding class="app-nav">
            <template
              v-for="(section, sectionIndex) in menuSections"
              :key="section.key"
            >
              <q-item-label header class="app-nav__header">
                <q-icon
                  v-if="section.icon"
                  :name="section.icon"
                  size="18px"
                  class="app-nav__header-icon"
                />
                <span>{{ section.label }}</span>
              </q-item-label>

              <q-item
                v-for="route in section.items"
                :key="route.path"
                clickable
                v-ripple
                :active="$route.path.startsWith(route.path)"
                :to="route.path"
                class="app-nav__item"
                active-class="app-nav__item--active"
              >
                <q-item-section avatar>
                  <q-icon
                    :name="
                      route.meta?.icon || section.icon || 'sym_o_dashboard'
                    "
                  />
                </q-item-section>
                <q-item-section>
                  <div class="app-nav__label">{{ route.meta?.title }}</div>
                  <div v-if="route.meta?.description" class="app-nav__caption">
                    {{ route.meta.description }}
                  </div>
                </q-item-section>
                <q-item-section side>
                  <q-icon
                    name="sym_o_chevron_right"
                    size="18px"
                    class="app-nav__chevron"
                  />
                </q-item-section>
              </q-item>

              <q-separator
                v-if="sectionIndex !== menuSections.length - 1"
                spaced
                inset
              />
            </template>
          </q-list>
        </template>

        <div v-else class="app-nav__empty">
          <q-icon name="sym_o_lock_person" size="36px" color="primary" />
          <div class="app-nav__empty-title">Nenhum menu disponível</div>
          <p class="app-nav__empty-text">
            Entre em contato com o administrador para habilitar as permissões
            necessárias.
          </p>
        </div>
      </q-scroll-area>

      <div class="app-drawer__footer">
        <div class="app-drawer__cta">
          <div class="app-drawer__cta-title">Precisa de ajuda?</div>
          <div class="app-drawer__cta-text">
            Nossa equipe está pronta para acelerar seus cortes.
          </div>
          <Button
            color="secondary"
            text-color="primary"
            variant="ghost"
            icon="sym_o_help"
            label="Abrir suporte"
            full-width
          />
        </div>
      </div>
    </q-drawer>

    <q-page-container>
      <div v-if="isLoginPage">
        <router-view />
      </div>
      <div v-else class="app-page">
        <router-view />
      </div>
    </q-page-container>
  </q-layout>
</template>

<script>
import { Dark } from "quasar";
import Cookies from "js-cookie";

import Button from "@components/Button";
import Toggle from "@components/Toggle";

import { API } from "@config/axios";
import { routes, MENUS } from "./auth/router";
import {
  buildUserProfileFromToken,
  extractUserInitials,
  mapRolesToAppRoles,
} from "@/utils/keycloak";

const MENU_CONFIG = {
  default: {
    label: "Navegação",
    icon: "sym_o_dashboard",
  },
  [MENUS.VIDEOS]: {
    label: "Vídeos",
    icon: "sym_o_video_library",
  },
  [MENUS.USUARIOS]: {
    label: "Usuários",
    icon: "sym_o_groups",
  },
};

export default {
  name: "App",
  components: {
    Button,
    Toggle,
  },
  data() {
    return {
      leftDrawerOpen: true,
      darkMode: Dark.isActive,
      logoutLoading: false,
      routes,
      userProfile: this.getInitialUserProfile(),
    };
  },
  computed: {
    navigationRoutes() {
      return this.routes.filter(
        (route) => route.meta?.showinModal && this.hasPermission(route)
      );
    },
    menuSections() {
      const groups = this.navigationRoutes.reduce((acc, route) => {
        const key = route.meta?.menu || "default";

        if (!acc[key]) {
          const config = MENU_CONFIG[key] || MENU_CONFIG.default || {};

          acc[key] = {
            key,
            label:
              config.label ||
              route.meta?.menuLabel ||
              route.meta?.title ||
              "Navegação",
            icon: config.icon,
            items: [],
          };
        }

        acc[key].items.push(route);

        return acc;
      }, {});

      return Object.values(groups).map((section) => ({
        ...section,
        items: section.items.sort((a, b) => {
          const orderA = a.meta?.order ?? 0;
          const orderB = b.meta?.order ?? 0;
          return orderA - orderB;
        }),
      }));
    },
    currentRouteTitle() {
      const route = this.$route;
      return route.meta?.title || route.name || "Clipper IA";
    },
    currentRouteDescription() {
      const current = this.$route.meta?.description;
      if (current) return current;

      const fallback = this.findParentRoute();

      return (
        fallback?.meta?.description || "Operacionalize cortes com inteligência."
      );
    },
    quickAction() {
      if (this.$route.meta?.quickAction === false) {
        return null;
      }

      if (this.$route.meta?.quickAction) {
        return this.$route.meta.quickAction;
      }

      const fallback = this.findParentRoute();

      return fallback?.meta?.quickAction || null;
    },
    isLoginPage() {
      return this.$route.path === "/login";
    },
    userRoles() {
      const profileRoles = Array.isArray(this.userProfile?.roles)
        ? this.userProfile.roles
        : [];
      const rawRoles = Array.isArray(this.userProfile?.rawRoles)
        ? this.userProfile.rawRoles
        : [];

      const canonical = mapRolesToAppRoles([...profileRoles, ...rawRoles]);

      return Array.from(new Set(canonical));
    },
    currentUserName() {
      return this.userProfile?.name || this.userProfile?.username || "";
    },
    currentUserEmail() {
      return this.userProfile?.email || this.userProfile?.username || "";
    },
    userInitials() {
      return extractUserInitials(this.currentUserName) || "CI";
    },
  },
  watch: {
    "$route.path"() {
      this.syncDrawerWithViewport();
      this.refreshUserProfile();
    },
  },
  mounted() {
    this.syncDrawerWithViewport();
    this.refreshUserProfile();
    window.addEventListener("resize", this.syncDrawerWithViewport);
  },
  beforeUnmount() {
    window.removeEventListener("resize", this.syncDrawerWithViewport);
  },
  methods: {
    toggleLeftDrawer() {
      this.leftDrawerOpen = !this.leftDrawerOpen;
    },
    toggleDarkMode() {
      Dark.toggle();
      this.darkMode = Dark.isActive;
    },
    handleQuickAction() {
      if (this.quickAction?.handler) {
        this.quickAction.handler();
        return;
      }

      if (this.quickAction?.to) {
        this.$router.push(this.quickAction.to);
      }
    },
    async handleLogout() {
      try {
        this.logoutLoading = true;

        await API.post("/auth/logout");

        const cookieRemovalOptions = { path: "/" };

        Cookies.remove("token", cookieRemovalOptions);
        Cookies.remove("refresh_token", cookieRemovalOptions);
        Cookies.remove("user_roles", cookieRemovalOptions);
        Cookies.remove("user_profile", cookieRemovalOptions);

        this.userProfile = { roles: [] };
        this.leftDrawerOpen = false;

        if (this.$route.path !== "/login") {
          this.$router.push("/login");
        }
      } catch (error) {
      } finally {
        this.logoutLoading = false;
      }
    },
    syncDrawerWithViewport() {
      if (window.innerWidth < 1024) {
        this.leftDrawerOpen = false;
      } else {
        this.leftDrawerOpen = true;
      }
    },
    findParentRoute() {
      const currentMenu = this.$route.meta?.menu;

      if (!currentMenu) {
        return this.navigationRoutes.find(
          (route) => route.path === this.$route.path
        );
      }

      return this.navigationRoutes.find(
        (route) => route.meta?.menu && route.meta.menu === currentMenu
      );
    },
    hasPermission(route) {
      const required = route.meta?.permissions;

      if (!Array.isArray(required) || required.length === 0) {
        return true;
      }

      return required.some((role) => this.userRoles.includes(role));
    },
    getInitialUserProfile() {
      const profileCookie = Cookies.get("user_profile");
      const rolesCookie = Cookies.get("user_roles");

      let profileFromCookie = null;

      if (profileCookie) {
        try {
          profileFromCookie = JSON.parse(profileCookie);
        } catch (error) {
          console.warn("Invalid user profile cookie", error);
        }
      }

      const collectedRawRoles = new Set();

      if (Array.isArray(profileFromCookie?.roles)) {
        profileFromCookie.roles.forEach((role) => collectedRawRoles.add(role));
      }

      if (Array.isArray(profileFromCookie?.rawRoles)) {
        profileFromCookie.rawRoles.forEach((role) =>
          collectedRawRoles.add(role)
        );
      }

      if (rolesCookie) {
        try {
          const parsedRoles = JSON.parse(rolesCookie);

          if (Array.isArray(parsedRoles)) {
            parsedRoles.forEach((role) => collectedRawRoles.add(role));
          }
        } catch (error) {
          console.warn("Invalid roles cookie", error);
        }
      }

      const combinedRawRoles = Array.from(collectedRawRoles);
      const mappedRoles = mapRolesToAppRoles(combinedRawRoles);

      if (profileFromCookie) {
        return {
          ...profileFromCookie,
          rawRoles: combinedRawRoles,
          roles: mappedRoles,
        };
      }

      const token = Cookies.get("token");

      if (!token) {
        if (mappedRoles.length) {
          return {
            roles: mappedRoles,
            rawRoles: combinedRawRoles,
          };
        }

        return { roles: [] };
      }

      const profile = buildUserProfileFromToken(token);

      if (!profile) {
        return { roles: [] };
      }

      const combinedFromToken = new Set([
        ...(profile.rawRoles || []),
        ...combinedRawRoles,
        ...(profile.roles || []),
      ]);

      const finalRawRoles = Array.from(combinedFromToken);
      const finalRoles = mapRolesToAppRoles(finalRawRoles);

      return {
        ...profile,
        rawRoles: finalRawRoles,
        roles: finalRoles,
      };
    },
    refreshUserProfile() {
      const profile = this.getInitialUserProfile();
      this.userProfile = profile || { roles: [] };
    },
  },
};
</script>

<style scoped lang="scss">
.app-shell {
  background: transparent;
}

.app-header {
  backdrop-filter: blur(18px);
  background: rgba(255, 255, 255, 0.92);
  border-bottom: 1px solid rgba(127, 86, 217, 0.12);
  padding: 10px clamp(12px, 2vw, 24px);
}

body.body--dark .app-header {
  background: rgba(16, 24, 40, 0.9);
  border-bottom-color: rgba(244, 235, 255, 0.08);
}

.app-toolbar {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(16px, 3vw, 40px);
}

.app-toolbar__page {
  display: flex;
  align-items: center;
  gap: 16px;
}

.app-toolbar__menu {
  display: none;
}

.app-toolbar__breadcrumbs {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.app-toolbar__eyebrow {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #7f56d9;
  font-weight: 600;
}

.app-toolbar__title {
  font-size: clamp(24px, 3vw, 32px);
  font-weight: 700;
  color: #101828;
  margin: 0;
}

.app-toolbar__subtitle {
  font-size: 14px;
  color: #475467;
  margin: 0;
  max-width: 420px;
}

body.body--dark .app-toolbar__eyebrow {
  color: #f4ebff;
}

body.body--dark .app-toolbar__title {
  color: rgba(255, 255, 255, 0.92);
}

body.body--dark .app-toolbar__subtitle {
  color: rgba(255, 255, 255, 0.7);
}

.app-toolbar__actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.app-toolbar__avatar-btn {
  padding: 0;
  min-width: 0;
}

.app-toolbar__avatar-btn .q-btn__content {
  padding: 0;
}

.app-toolbar__icon {
  background: rgba(127, 86, 217, 0.08);
  color: #53389e;
}

body.body--dark .app-toolbar__icon {
  background: rgba(244, 235, 255, 0.12);
  color: #f4ebff;
}

.app-toolbar__avatar {
  background: rgba(127, 86, 217, 0.16);
  color: #53389e;
  font-weight: 600;
}

body.body--dark .app-toolbar__avatar {
  background: rgba(244, 235, 255, 0.2);
  color: #0b1120;
}

.app-user-menu {
  min-width: 240px;
  padding: 12px 0;
}

.app-user-menu__header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px 8px;
}

.app-user-menu__info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.app-user-menu__name {
  font-weight: 600;
  color: #101828;
}

.app-user-menu__email {
  font-size: 13px;
  color: #667085;
}

.app-user-menu__list .q-item {
  border-radius: 12px;
}

.app-user-menu__list .q-item:not(.q-item--disabled):hover {
  background: rgba(127, 86, 217, 0.08);
}

body.body--dark .app-user-menu__name {
  color: rgba(255, 255, 255, 0.9);
}

body.body--dark .app-user-menu__email {
  color: rgba(255, 255, 255, 0.65);
}

body.body--dark .app-user-menu__list .q-item:not(.q-item--disabled):hover {
  background: rgba(244, 235, 255, 0.12);
}

.app-drawer {
  padding: 24px 0 16px;
  border-right: none;
  background: #ffffff;
}

body.body--dark .app-drawer {
  background: rgba(16, 24, 40, 0.96);
}

.app-drawer__header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px 24px;
}

.app-drawer__brand {
  font-weight: 700;
  font-size: 18px;
  color: #101828;
}

.app-drawer__tag {
  font-size: 13px;
  color: #667085;
}

body.body--dark .app-drawer__brand {
  color: rgba(255, 255, 255, 0.92);
}

body.body--dark .app-drawer__tag {
  color: rgba(255, 255, 255, 0.55);
}

.app-nav {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.app-nav__header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #98a2b3;
}

.app-nav__header-icon {
  color: #7f56d9;
}

.app-nav__item {
  border-radius: 14px;
  margin: 0 12px;
  padding: 12px;
  transition: background 0.2s ease, transform 0.2s ease;
}

.app-nav__item:hover {
  background: rgba(127, 86, 217, 0.08);
  transform: translateX(4px);
}

.app-nav__item--active {
  background: rgba(127, 86, 217, 0.16);
  color: #53389e;
}

.app-nav__label {
  font-weight: 600;
  color: #101828;
}

.app-nav__caption {
  font-size: 12px;
  color: #667085;
}

.app-nav__chevron {
  color: #c7c9d9;
}

body.body--dark .app-nav__item:hover {
  background: rgba(244, 235, 255, 0.1);
}

body.body--dark .app-nav__item--active {
  background: rgba(244, 235, 255, 0.18);
  color: rgba(255, 255, 255, 0.9);
}

body.body--dark .app-nav__label {
  color: rgba(255, 255, 255, 0.9);
}

body.body--dark .app-nav__caption {
  color: rgba(255, 255, 255, 0.6);
}

body.body--dark .app-nav__chevron {
  color: rgba(244, 235, 255, 0.4);
}

.app-nav__empty {
  padding: 48px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  color: #475467;
}

.app-nav__empty-title {
  font-weight: 600;
  color: #101828;
}

.app-nav__empty-text {
  margin: 0;
  font-size: 13px;
  color: #667085;
}

body.body--dark .app-nav__header-icon {
  color: #f4ebff;
}

body.body--dark .app-nav__empty-title {
  color: rgba(255, 255, 255, 0.9);
}

body.body--dark .app-nav__empty-text {
  color: rgba(255, 255, 255, 0.6);
}

.app-drawer__footer {
  padding: 24px;
}

.app-drawer__cta {
  background: rgba(127, 86, 217, 0.12);
  border-radius: 16px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.app-drawer__cta-title {
  font-size: 15px;
  font-weight: 600;
  color: #53389e;
}

.app-drawer__cta-text {
  font-size: 13px;
  color: #475467;
}

body.body--dark .app-drawer__cta {
  background: rgba(244, 235, 255, 0.12);
}

body.body--dark .app-drawer__cta-title {
  color: rgba(255, 255, 255, 0.9);
}

body.body--dark .app-drawer__cta-text {
  color: rgba(255, 255, 255, 0.7);
}

@media (max-width: 1024px) {
  .app-toolbar__menu {
    display: inline-flex;
  }

  .app-drawer {
    background: #ffffff;
  }
}

@media (max-width: 768px) {
  .app-toolbar__actions {
    gap: 8px;
  }

  .app-toolbar__subtitle {
    max-width: 280px;
  }

  .app-toolbar__icon,
  .app-toolbar__avatar {
    display: none;
  }
}
</style>
