<template>
  <main class="container page-padding">
    <!-- <h1 class="mb-3">Your Groups</h1> -->

    <div v-if="fetchError" class="alert alert-error mb-3" role="alert">
      <div class="alert-content">
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-alert-triangle" />
        </svg>
        {{ fetchError }}
      </div>
      <button type="button" class="btn btn-sm btn-danger" @click="fetchGroups">Retry</button>
    </div>

    <div v-else-if="groups.length === 0" class="card empty-state-card">
      <svg class="icon icon-lg" aria-hidden="true">
        <use xlink:href="#icon-clipboard" />
      </svg>
      <h3>No Groups Yet!</h3>
      <p>You are not a member of any groups yet. Create one or join using an invite code.</p>
      <button class="btn btn-primary mt-2" @click="openCreateGroupDialog">
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-plus" />
        </svg>
        Create New Group
      </button>
    </div>

    <div v-else class="mb-3">
      <div class="neo-groups-grid">
        <div v-for="group in groups" :key="group.id" class="neo-group-card" @click="selectGroup(group)">
          <h1 class="neo-group-header">{{ group.name }}</h1>
          <div class="neo-group-actions">
            <button class="btn btn-sm btn-secondary" @click.stop="openCreateListDialog(group)">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-plus" />
              </svg>
              List
            </button>
          </div>
        </div>
        <div class="neo-create-group-card" @click="openCreateGroupDialog">
          + Group
        </div>
      </div>

      <details class="card mb-3 mt-4">
        <summary class="card-header flex items-center cursor-pointer justify-between">
          <h3>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-user" />
            </svg>
            Join a Group with Invite Code
          </h3>
          <span class="expand-icon" aria-hidden="true">▼</span>
        </summary>
        <div class="card-body">
          <form @submit.prevent="handleJoinGroup" class="flex items-center" style="gap: 0.5rem;">
            <div class="form-group flex-grow" style="margin-bottom: 0;">
              <label for="joinInviteCodeInput" class="sr-only">Enter Invite Code</label>
              <input type="text" id="joinInviteCodeInput" v-model="inviteCodeToJoin" class="form-input"
                placeholder="Enter Invite Code" required ref="joinInviteCodeInputRef" />
            </div>
            <button type="submit" class="btn btn-secondary" :disabled="joiningGroup">
              <span v-if="joiningGroup" class="spinner-dots-sm" role="status"><span /><span /><span /></span>
              Join
            </button>
          </form>
          <p v-if="joinGroupFormError" class="form-error-text mt-1">{{ joinGroupFormError }}</p>
        </div>
      </details>
    </div>

    <!-- Create Group Dialog -->
    <div v-if="showCreateGroupDialog" class="modal-backdrop open" @click.self="closeCreateGroupDialog">
      <div class="modal-container" ref="createGroupModalRef" role="dialog" aria-modal="true"
        aria-labelledby="createGroupTitle">
        <div class="modal-header">
          <h3 id="createGroupTitle">Create New Group</h3>
          <button class="close-button" @click="closeCreateGroupDialog" aria-label="Close">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-close" />
            </svg>
          </button>
        </div>
        <form @submit.prevent="handleCreateGroup">
          <div class="modal-body">
            <div class="form-group">
              <label for="newGroupNameInput" class="form-label">Group Name</label>
              <input type="text" id="newGroupNameInput" v-model="newGroupName" class="form-input" required
                ref="newGroupNameInputRef" />
              <p v-if="createGroupFormError" class="form-error-text">{{ createGroupFormError }}</p>
            </div>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-neutral" @click="closeCreateGroupDialog">Cancel</button>
            <button type="submit" class="btn btn-primary ml-2" :disabled="creatingGroup">
              <span v-if="creatingGroup" class="spinner-dots-sm" role="status"><span /><span /><span /></span>
              Create
            </button>
          </div>
        </form>
      </div>
    </div>

    <!-- Create List Modal -->
    <CreateListModal v-model="showCreateListModal" :groups="availableGroupsForModal" @created="onListCreated" />
  </main>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { apiClient, API_ENDPOINTS } from '@/config/api';
import { useStorage } from '@vueuse/core';
import { onClickOutside } from '@vueuse/core';
import { useNotificationStore } from '@/stores/notifications';
import CreateListModal from '@/components/CreateListModal.vue';

interface Group {
  id: number;
  name: string;
  description?: string;
  member_count: number;
  created_at: string;
  updated_at: string;
}

const router = useRouter();
const notificationStore = useNotificationStore();
const groups = ref<Group[]>([]);
const loading = ref(false);
const fetchError = ref<string | null>(null);

const showCreateGroupDialog = ref(false);
const newGroupName = ref('');
const creatingGroup = ref(false);
const newGroupNameInputRef = ref<HTMLInputElement | null>(null);
const createGroupModalRef = ref<HTMLElement | null>(null);
const createGroupFormError = ref<string | null>(null);

const inviteCodeToJoin = ref('');
const joiningGroup = ref(false);
const joinInviteCodeInputRef = ref<HTMLInputElement | null>(null);
const joinGroupFormError = ref<string | null>(null);

const showCreateListModal = ref(false);
const availableGroupsForModal = ref<{ label: string; value: number; }[]>([]);

// Cache groups in localStorage
const cachedGroups = useStorage<Group[]>('cached-groups', []);
const cachedTimestamp = useStorage<number>('cached-groups-timestamp', 0);
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds

// Load cached data immediately if available and not expired
const loadCachedData = () => {
  const now = Date.now();
  if (cachedGroups.value.length > 0 && (now - cachedTimestamp.value) < CACHE_DURATION) {
    groups.value = cachedGroups.value;
  }
};

// Fetch fresh data from API
const fetchGroups = async () => {
  try {
    const response = await apiClient.get(API_ENDPOINTS.GROUPS.BASE);
    groups.value = response.data;

    // Update cache
    cachedGroups.value = response.data;
    cachedTimestamp.value = Date.now();
  } catch (err) {
    fetchError.value = err instanceof Error ? err.message : 'Failed to load groups';
    // If we have cached data, keep showing it even if refresh failed
    if (cachedGroups.value.length === 0) {
      groups.value = [];
    }
  }
};

const openCreateGroupDialog = () => {
  newGroupName.value = '';
  createGroupFormError.value = null;
  showCreateGroupDialog.value = true;
  nextTick(() => {
    newGroupNameInputRef.value?.focus();
  });
};

const closeCreateGroupDialog = () => {
  showCreateGroupDialog.value = false;
};

onClickOutside(createGroupModalRef, closeCreateGroupDialog);

const handleCreateGroup = async () => {
  if (!newGroupName.value.trim()) {
    createGroupFormError.value = 'Group name is required';
    newGroupNameInputRef.value?.focus();
    return;
  }
  createGroupFormError.value = null;
  creatingGroup.value = true;
  try {
    const response = await apiClient.post(API_ENDPOINTS.GROUPS.BASE, {
      name: newGroupName.value,
    });
    const newGroup = response.data as Group;
    if (newGroup && newGroup.id && newGroup.name) {
      groups.value.push(newGroup);
      closeCreateGroupDialog();
      notificationStore.addNotification({ message: `Group '${newGroup.name}' created successfully.`, type: 'success' });
      // Update cache
      cachedGroups.value = groups.value;
      cachedTimestamp.value = Date.now();
    } else {
      throw new Error('Invalid data received from server.');
    }
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : 'Failed to create group. Please try again.';
    createGroupFormError.value = message;
    console.error('Error creating group:', error);
    notificationStore.addNotification({ message, type: 'error' });
  } finally {
    creatingGroup.value = false;
  }
};

const handleJoinGroup = async () => {
  if (!inviteCodeToJoin.value.trim()) {
    joinGroupFormError.value = 'Invite code is required';
    joinInviteCodeInputRef.value?.focus();
    return;
  }
  joinGroupFormError.value = null;
  joiningGroup.value = true;
  try {
    const response = await apiClient.post(API_ENDPOINTS.INVITES.ACCEPT(inviteCodeToJoin.value));
    const joinedGroup = response.data as Group; // Adjust based on actual API response for joined group
    if (joinedGroup && joinedGroup.id && joinedGroup.name) {
      // Check if group already in list to prevent duplicates if API returns the group info
      if (!groups.value.find(g => g.id === joinedGroup.id)) {
        groups.value.push(joinedGroup);
      }
      inviteCodeToJoin.value = '';
      notificationStore.addNotification({ message: `Successfully joined group '${joinedGroup.name}'.`, type: 'success' });
      // Update cache
      cachedGroups.value = groups.value;
      cachedTimestamp.value = Date.now();
    } else {
      // If API returns only success message, re-fetch groups
      await fetchGroups(); // Refresh the list of groups
      inviteCodeToJoin.value = '';
      notificationStore.addNotification({ message: `Successfully joined group.`, type: 'success' });
    }
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : 'Failed to join group. Please check the invite code and try again.';
    joinGroupFormError.value = message;
    console.error('Error joining group:', error);
    notificationStore.addNotification({ message, type: 'error' });
  } finally {
    joiningGroup.value = false;
  }
};

const selectGroup = (group: Group) => {
  router.push(`/groups/${group.id}`);
};

const openCreateListDialog = (group: Group) => {
  availableGroupsForModal.value = [{
    label: group.name,
    value: group.id
  }];
  showCreateListModal.value = true;
};

const onListCreated = (newList: any) => {
  notificationStore.addNotification({
    message: `List '${newList.name}' created successfully.`,
    type: 'success'
  });
};

onMounted(async () => {
  // Load cached data immediately
  loadCachedData();

  // Then fetch fresh data in background
  await fetchGroups();
});
</script>

<style scoped>
.page-padding {
  padding: 1rem;
  max-width: 1200px;
  margin: 0 auto;
}

.mb-3 {
  margin-bottom: 1.5rem;
}

.mt-4 {
  margin-top: 2rem;
}

.mt-1 {
  margin-top: 0.5rem;
}

.ml-2 {
  margin-left: 0.5rem;
}

/* Responsive grid for cards */
.neo-groups-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: center;
  align-items: flex-start;
  margin-bottom: 2rem;
}

/* Card styles */
.neo-group-card,
.neo-create-group-card {
  border-radius: 18px;
  box-shadow: 6px 6px 0 #111;
  max-width: 420px;
  min-width: 260px;
  width: 100%;
  margin: 0 auto;
  border: none;
  background: var(--light);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0;
  padding: 2rem 2rem 1.5rem 2rem;
  cursor: pointer;
  transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out;
  border: 3px solid #111;
}

.neo-group-card:hover {
  transform: translateY(-3px);
  box-shadow: 6px 9px 0 #111;
}

.neo-group-header {
  font-weight: 900;
  font-size: 1.25rem;
  /* margin-bottom: 1rem; */
  letter-spacing: 0.5px;
  text-transform: none;
}

.neo-group-actions {
  margin-top: 0;
}

.neo-create-group-card {
  border: 3px dashed #111;
  background: var(--light);
  padding: 2.5rem 0;
  text-align: center;
  font-weight: 900;
  font-size: 1.1rem;
  color: #222;
  cursor: pointer;
  margin-top: 0;
  transition: background 0.1s;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  margin-bottom: 2.5rem;
}

.neo-create-group-card:hover {
  background: #f0f0f0;
}

.form-error-text {
  color: var(--danger);
  font-size: 0.85rem;
}

.flex-grow {
  flex-grow: 1;
}

details>summary {
  list-style: none;
}

details>summary::-webkit-details-marker {
  display: none;
}

.expand-icon {
  transition: transform 0.2s ease-in-out;
}

details[open] .expand-icon {
  transform: rotate(180deg);
}

.cursor-pointer {
  cursor: pointer;
}

/* Responsive adjustments */
@media (max-width: 900px) {
  .neo-groups-grid {
    gap: 1.2rem;
  }

  .neo-group-card,
  .neo-create-group-card {
    max-width: 95vw;
    min-width: 180px;
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

@media (max-width: 600px) {
  .page-padding {
    padding: 0.5rem;
  }

  .neo-group-card,
  .neo-create-group-card {
    padding: 1.2rem 0.7rem 1rem 0.7rem;
    font-size: 1rem;
  }

  .neo-group-header {
    font-size: 1.1rem;
  }
}
</style>