<template>
  <div id="app">
    <AppHeader @toggle-sidebar="sidebarVisible = !sidebarVisible" />
    <Toast />
    <template v-if="isRouterReady">
      <AppPublicLayout v-if="isPublicLayout">
        <router-view />
      </AppPublicLayout>
      <div v-else class="app">
        <div class="app-content">
          <div v-if="sidebarVisible && isMobileView" class="sidebar-overlay" @click="closeSidebar"></div>
          <aside v-if="isLoggedIn" class="sidebar" :class="{ 'mobile-visible': sidebarVisible, 'mobile-hidden': !sidebarVisible && isMobileView }">
            <div class="sidebar-content">
              <!-- 클럽 정보 -->
              <div class="club-info" v-if="selectedClub">
                <div class="club-header">
                  <div class="club-title">
                    <h3>{{ selectedClub.name }}</h3>
                    <router-link v-if="userRole === 'admin' || userClubRole === '모임장'" 
                      :to="{ name: 'ClubSettings' }" 
                      class="settings-icon" 
                      title="클럽 설정">
                      <i class="pi pi-cog"></i>
                    </router-link>
                  </div>
                  <p class="club-location"><i class="pi pi-map-marker"></i> {{ selectedClub.location }}</p>
                </div>
                <div class="club-stats">
                  <div class="stat-item">
                    <i class="pi pi-users"></i>
                    <span>{{ memberCount }} 명</span>
                  </div>
                  <div class="stat-item">
                    <i class="pi pi-user"></i>
                    <span>모임장: {{ ownerName }}</span>
                  </div>
                </div>
              </div>
              <!-- 클럽 선택 기능 (관리자 또는 클럽이 2개 이상) -->
              <div v-if="isAdmin || clubs.length > 1" class="club-selector">
                <label for="club-select">클럽 선택:</label>
                <select id="club-select" v-model="selectedClubId" @change="onClubChange">
                  <option v-for="club in clubs" :key="club.id" :value="club.id">{{ club.name }}({{ club.memberType }})</option>
                </select>
              </div>
              <!-- 커스텀 사이드바 메뉴 -->
              <div class="custom-sidebar-menu" :class="{ mobile: isMobileView }" v-show="sidebarVisible">
                <template v-for="(menuGroup, groupIndex) in menuItems" :key="groupIndex">
                  <div class="menu-group">
                    <div class="menu-group-header" @click="toggleMenuGroup(groupIndex)">
                      <i :class="menuGroup.icon"></i>
                      <span>{{ menuGroup.label }}</span>
                      <i class="pi" :class="expandedGroups[groupIndex] ? 'pi-chevron-down' : 'pi-chevron-right'"></i>
                    </div>
                    <div class="menu-items" v-if="expandedGroups[groupIndex]" v-show="menuGroup.items && menuGroup.items.length">
                      <router-link 
                        v-for="(item, itemIndex) in menuGroup.items" 
                        :key="itemIndex"
                        :to="item.to"
                        class="menu-item"
                        exact
                        active-class="router-link-active"
                        @click="closeSidebarOnMobile"
                      >
                        <i :class="item.icon"></i>
                        <span>{{ item.label }}</span>
                      </router-link>
                    </div>
                  </div>
                </template>
                <!-- 그룹이 없는 단일 메뉴 아이템 -->
                <div v-for="(menuItem, itemIndex) in singleMenuItems" :key="'single-'+itemIndex">
                  <router-link 
                    :to="menuItem.to"
                    class="menu-item single-menu-item"
                    exact
                    active-class="router-link-active"
                    @click="closeSidebarOnMobile"
                  >
                    <i :class="menuItem.icon"></i>
                    <span>{{ menuItem.label }}</span>
                  </router-link>
                </div>
              </div>
            </div>
          </aside>
          <main class="main-content" :class="{ 'full-width': !isLoggedIn }">
            <router-view />
          </main>
        </div>
        <footer>
          <p>&copy; {{ new Date().getFullYear() }} 볼링 클럽 매니저. All rights reserved.</p>
        </footer>
      </div>
    </template>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, provide, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import apiClient from './services/api';
import authService from './services/authService';
import { useClubStore } from './stores/clubStore';
import AppPublicLayout from './layouts/AppPublicLayout.vue';
import AppHeader from './components/AppHeader.vue';

const route = useRoute();
const layoutComponent = computed(() => route.meta.layout === 'public' ? AppPublicLayout : 'div');
const isPublicLayout = computed(() => {
  // 라우트 meta.layout이 public이거나, 경로가 /public/로 시작하면 public 레이아웃으로 간주
  return route.meta.layout === 'public' || route.path.startsWith('/public/');
});

// 클럽 스토어 초기화
const clubStore = useClubStore();

// 상태 변수
const user = ref(null);
provide('user', user);
const menuItems = ref([]);
const singleMenuItems = ref([]); 
const expandedGroups = ref({});
const isMobileView = ref(window.innerWidth < 768);
const sidebarVisible = ref(window.innerWidth > 600);
const isLoggedIn = computed(() => !!user.value && !!localStorage.getItem('token'));
const clubs = ref([]); // 클럽 목록
const selectedClubId = ref(localStorage.getItem('clubId') || null); // 선택된 클럽 ID
const selectedClub = ref(null);
const memberCount = ref(0);
const ownerName = ref('');
const isRouterReady = ref(false);
const userRole = computed(() => user.value?.role || '');
const isAdmin = computed(() => userRole.value === 'admin' || userRole.value === 'superadmin');
const userClubRole = computed(() => localStorage.getItem('userClubRole') || '');

// 화면 크기 변경 감지
const handleResize = () => {
  isMobileView.value = window.innerWidth < 768;
  sidebarVisible.value = window.innerWidth > 600;
};

// 사이드바 토글
const toggleSidebar = () => {
  sidebarVisible.value = !sidebarVisible.value;
};

// 사이드바 닫기
const closeSidebar = () => {
  if (isMobileView.value) {
    sidebarVisible.value = false;
  }
};

// 모바일에서 메뉴 아이템 클릭 시 사이드바 닫기
const closeSidebarOnMobile = () => {
  if (isMobileView.value) {
    closeSidebar();
  }
};

// 메뉴 그룹 토글
const toggleMenuGroup = (groupIndex) => {
  expandedGroups.value[groupIndex] = !expandedGroups.value[groupIndex];
};

// 모든 메뉴 그룹 초기화 (모두 펼치기)
const initializeExpandedGroups = () => {
  menuItems.value.forEach((_, index) => {
    expandedGroups.value[index] = true;
  });
};

// 클럽 목록 가져오기
const fetchClubs = async () => {
  if (isPublicLayout.value) return;
  try {
    const userId = user.value?.id;
    const userRole = localStorage.getItem('userRole');
    
    const response = await apiClient.post('/api/club/user', {
      userId,
      role: userRole
    });
    
    clubs.value = response.data.map(club => ({
      ...club,
      memberType: club.memberType || ''
    }));
    // 첫 번째 클럽의 memberType을 localStorage에 저장
    if ((clubs.value.length > 0 && !selectedClubId.value) || clubs.value.length === 1) {
      selectedClubId.value = clubs.value[0].id;
      await setSelectedClub(clubs.value[0]);
    }
  } catch (error) {
    console.error('클럽 목록 로드 실패:', error);
    
    // 클럽 목록을 가져오지 못했거나 클럽이 없는 경우
    const userRole = localStorage.getItem('userRole');
    // 관리자가 아닌 경우에만 클럽 생성 페이지로 리다이렉트
    if (userRole !== 'admin' && userRole !== 'superadmin') {
      router.push('/club/create');
    }
  }
};

// 클럽 정보 가져오기
const fetchClubInfo = async () => {
  if (isPublicLayout.value) return;
  try {
    // 클럽 스토어를 통해 클럽 정보 가져오기
    const clubId = selectedClubId.value ?? (clubs.value.length > 0 ? clubs.value[0].id : null);
    if (!clubId) return;
    
    const clubData = await clubStore.fetchClubById(clubId);

    if (clubData) {
      selectedClub.value = {
        id: clubData.id,
        name: clubData.name,
        location: clubData.location,
        subscription: clubData.subscription || null
      };
      memberCount.value = clubData.memberCount;
      ownerName.value = clubData.ownerName;
    }
  } catch (error) {
    console.error('클럽 정보 가져오기 오류:', error);
  }
};

// 클럽 선택
const setSelectedClub = async (club) => {
  if (isPublicLayout.value) return;
  // 1. localStorage에 저장
  localStorage.setItem('clubId', club.id);
  localStorage.setItem('userClubRole', club.memberType || '');

  // 2. 세션에도 저장 (백엔드에 clubId 전달)
  try {
    await apiClient.post('/api/club/select-club', { clubId: club.id });
  } catch (error) {
    console.error('클럽 ID 세션 저장 실패:', error);
  }

  // 3. 프론트엔드 상태도 변경
  selectedClubId.value = club.id;
};

// 클럽 변경 시
const router = useRouter();
const onClubChange = async () => {
  try {
    const selectedClub = clubs.value.find(club => club.id === selectedClubId.value);
    if (selectedClub) {
      await setSelectedClub(selectedClub);
    }

    await fetchClubInfo();
    loadMenuItems();
    
    // 라우터의 네비게이션을 강제로 새로고침
    router.go(0);
  } catch (error) {
    console.error('클럽 변경 실패:', error);
  }
};

// 메뉴 아이템 로드
const loadMenuItems = async () => {
  if (isPublicLayout.value) return;
  try {
    const role = localStorage.getItem('userRole');
    const clubId = selectedClubId.value;
    
    if (!clubId) {
      throw new Error('클럽 ID가 없습니다.');
    }
    
    try {
      const response = await apiClient.post(`/api/menus`, {
        role: role,
        clubId: clubId
      });
      
      if (response.data && response.data.success && response.data.data && response.data.data.length > 0) {
        const groupMenus = [];
        const singleMenus = [];

        // 서버에서 받은 메뉴 처리 (관리자 메뉴 제외)
        response.data.data
          .forEach(menuGroup => {
            if (menuGroup.children && menuGroup.children.length > 0) {
              const processedItems = menuGroup.children.map(item => ({
                label: item.title,
                icon: item.icon,
                to: item.to
              }));
              
              groupMenus.push({
                label: menuGroup.title,
                icon: menuGroup.icon,
                items: processedItems
              });
            } else if (menuGroup.to) {
              singleMenus.push({
                label: menuGroup.title,
                icon: menuGroup.icon,
                to: menuGroup.to
              });
            }
          });

        menuItems.value = groupMenus;
        singleMenuItems.value = singleMenus;
      } else {
        menuItems.value = [];
        singleMenuItems.value = [];
      }
    } catch (error) {
      console.error('메뉴 아이템 로드 오류:', error);
      menuItems.value = [];
      singleMenuItems.value = [];
    }

    initializeExpandedGroups();
  } catch (error) {
    console.error('메뉴 아이템 로드 오류:', error);
    menuItems.value = [];
    singleMenuItems.value = [];
  }
};

// 사이드바 새로고침 메소드
const refreshSidebar = async () => {
  console.log('사이드바 새로고침 시작...');
  await fetchClubs();
  await fetchClubInfo();
  loadMenuItems();
  initializeExpandedGroups(); // 메뉴 그룹 초기화
  console.log('사이드바 새로고침 완료');
};

// 사이드바 새로고침 메소드를 전역으로 노출
provide('refreshSidebar', refreshSidebar);

// 사용자 정보 로드
const loadUserData = async () => {
  const token = localStorage.getItem('token');
  if (token) {
    try {
      const response = await authService.getCurrentUser();
      user.value = response.data;
      localStorage.setItem('userRole', response.data.role);
    } catch (error) {
      console.error('사용자 정보 로드 실패:', error);
    }
  }
};

// 로그인 성공 후 상태 갱신 핸들러
const handleUserLoggedIn = async () => {
  await loadUserData();
  if (isLoggedIn.value) {
    await fetchClubs();
    await fetchClubInfo();
    loadMenuItems();
  }
};

// 컴포넌트 마운트 시 데이터 로드
onMounted(async () => {
  await router.isReady?.()
  isRouterReady.value = true
  // public 레이아웃이면 내부 데이터 로딩/초기화 완전 스킵
  if (isPublicLayout.value) {
    window.addEventListener('resize', handleResize);
    window.addEventListener('user-logged-in', handleUserLoggedIn);
    initializeExpandedGroups();
    return;
  }
  // 내부(클럽) 페이지만 내부 데이터 로딩
  await loadUserData();
  const clubId = localStorage.getItem('clubId');
  if (clubId) {
    apiClient.post('/api/club/select-club', { clubId });
  }
  if (isLoggedIn.value) {
    await fetchClubs();
    await fetchClubInfo();
    loadMenuItems();
  }
  window.addEventListener('resize', handleResize);
  window.addEventListener('user-logged-in', handleUserLoggedIn);
  initializeExpandedGroups();
});

// 컴포넌트 언마운트 시 이벤트 리스너 제거
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  window.removeEventListener('user-logged-in', handleUserLoggedIn);
});
</script>
<style>
body {
  margin: 0;
  padding: 0;
}
</style>
<style scoped>
/* App.vue 스타일 */
.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.app-content {
  display: flex;
  flex: 1;
}

/* 사이드바 스타일 */
.sidebar {
  width: 250px;
  background-color: #f8f9fa;
  border-right: 1px solid #dee2e6;
  transition: all 0.3s ease;
  position: relative;
  z-index: 2;
}

.sidebar.mobile-visible {
  transform: translateX(0);
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
}

.sidebar.mobile-hidden {
  transform: translateX(-100%);
}

.sidebar-content {
  padding: 20px;
}

.club-info {
  margin-bottom: 20px;
}

.club-header {
  margin-bottom: 10px;
}

.club-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 5px;
}

.club-header h3 {
  margin: 0;
  font-size: 1.2em;
  font-weight: bold;
}

.settings-icon {
  color: #6c757d;
  font-size: 1.1em;
  transition: color 0.3s ease;
}

.settings-icon:hover {
  color: #007bff;
}

.club-location {
  margin: 0;
  font-size: 0.9em;
  color: #6c757d;
}

.club-stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.stat-item {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
}

.stat-item i {
  margin-right: 5px;
  font-size: 1em;
}

.stat-item span {
  font-size: 0.9em;
}

/* 클럽 선택 스타일 */
.club-selector {
  margin-bottom: 20px;
}

.club-selector label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

.club-selector select {
  width: 100%;
  padding: 8px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  box-sizing: border-box;
}

/* 사이드바 메뉴 스타일 */
.custom-sidebar-menu {
  margin-top: 20px;
}
.custom-sidebar-menu.mobile {
  position: fixed;
  left: 0;
  width: 200px;
  height: 100%;
  z-index: 1200;
  background: #fff;
  box-shadow: 2px 0 8px rgba(0,0,0,0.1);
  transition: left 0.2s;
}


.menu-group-header {
  display: flex;
  align-items: center;
  padding: 10px 15px;
  background-color: #e9ecef;
  border-radius: 5px;
  margin-bottom: 5px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.menu-group-header:hover {
  background-color: #dee2e6;
}

.menu-group-header i {
  margin-right: 10px;
  font-size: 1.1em;
}

.menu-group-header span {
  font-weight: bold;
}

.menu-items {
  padding-left: 15px;
  margin-bottom: 10px;
}

.menu-item {
  display: flex;
  align-items: center;
  padding: 8px 15px;
  border-radius: 5px;
  text-decoration: none;
  color: #495057;
  transition: background-color 0.3s ease;
}

.menu-item:hover {
  background-color: #f1f3f5;
}

.menu-item i {
  margin-right: 10px;
  font-size: 1em;
}

.menu-item span {
  font-size: 1em;
}

.router-link-active {
  background-color: #007bff;
  color: white;
}

.router-link-active:hover {
  background-color: #0069d9;
}

.single-menu-item {
  margin-bottom: 5px;
}

/* 메인 컨텐츠 스타일 */
.main-content {
  width: 100%;
  flex: 1;
  padding: 20px;
  transition: margin-left 0.3s ease;
  box-sizing: border-box;
}

.main-content.full-width {
  margin-left: 0;
}

/* 푸터 스타일 */
footer {
  background-color: #343a40;
  color: white;
  text-align: center;
  padding: 10px;
}

/* 사이드바 오버레이 스타일 */
.sidebar-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1;
}

/* 미디어 쿼리 (모바일 뷰) */
@media (max-width: 767px) {
  .sidebar {
    width: 200px;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 3;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
  }

  .main-content {
    padding: 10px;
  }
}
</style>
