<template>
  <main class="container page-padding">
    <div v-if="loading" class="text-center">
      <VSpinner :label="t('groupDetailPage.loadingLabel')" />
    </div>
    <VAlert v-else-if="error" type="error" :message="error" class="mb-3">
      <template #actions>
        <VButton variant="danger" size="sm" @click="fetchGroupDetails">{{ t('groupDetailPage.retryButton') }}</VButton>
      </template>
    </VAlert>
    <div v-else-if="group">
      <VHeading level="1" :text="group.name" class="mb-3" />

      <div class="neo-grid">
        <!-- Group Members Section -->
        <VCard>
          <template #header><VHeading level="3">{{ t('groupDetailPage.members.title') }}</VHeading></template>
          <VList v-if="group.members && group.members.length > 0">
            <VListItem v-for="member in group.members" :key="member.id" class="flex justify-between items-center">
              <div class="neo-member-info">
                <span class="neo-member-name">{{ member.email }}</span>
                <VBadge :text="member.role || t('groupDetailPage.members.defaultRole')" :variant="member.role?.toLowerCase() === 'owner' ? 'primary' : 'secondary'" />
              </div>
              <VButton v-if="canRemoveMember(member)" variant="danger" size="sm" @click="removeMember(member.id)" :disabled="removingMember === member.id">
                <VSpinner v-if="removingMember === member.id" size="sm"/> {{ t('groupDetailPage.members.removeButton') }}
              </VButton>
            </VListItem>
          </VList>
          <div v-else class="text-center py-4">
            <VIcon name="users" size="lg" class="opacity-50 mb-2" />
            <p>{{ t('groupDetailPage.members.emptyState') }}</p>
          </div>
        </VCard>

        <!-- Invite Members Section -->
        <VCard>
          <template #header><VHeading level="3">{{ t('groupDetailPage.invites.title') }}</VHeading></template>
          <VButton variant="primary" class="w-full" @click="generateInviteCode" :disabled="generatingInvite">
            <VSpinner v-if="generatingInvite" size="sm"/> {{ inviteCode ? t('groupDetailPage.invites.regenerateButton') : t('groupDetailPage.invites.generateButton') }}
          </VButton>
          <div v-if="inviteCode" class="neo-invite-code mt-3">
            <VFormField :label="t('groupDetailPage.invites.activeCodeLabel')" :label-sr-only="false">
              <div class="flex items-center gap-2">
                <VInput id="inviteCodeInput" :model-value="inviteCode" readonly class="flex-grow" />
                <VButton variant="neutral" :icon-only="true" iconLeft="clipboard" @click="copyInviteCodeHandler" :aria-label="t('groupDetailPage.invites.copyButtonLabel')" />
              </div>
            </VFormField>
            <p v-if="copySuccess" class="text-sm text-green-600 mt-1">{{ t('groupDetailPage.invites.copySuccess') }}</p>
          </div>
          <div v-else class="text-center py-4 mt-3">
            <VIcon name="link" size="lg" class="opacity-50 mb-2" />
            <p>{{ t('groupDetailPage.invites.emptyState') }}</p>
          </div>
        </VCard>
      </div>

      <!-- Lists Section -->
      <div class="mt-4">
        <ListsPage :group-id="groupId" />
      </div>

      <!-- Chores Section -->
      <VCard class="mt-4">
        <template #header>
          <div class="flex justify-between items-center w-full">
            <VHeading level="3">{{ t('groupDetailPage.chores.title') }}</VHeading>
            <VButton :to="`/groups/${groupId}/chores`" variant="primary">
              <span class="material-icons" style="margin-right: 0.25em;">cleaning_services</span> {{ t('groupDetailPage.chores.manageButton') }}
            </VButton>
          </div>
        </template>
        <VList v-if="upcomingChores.length > 0">
          <VListItem v-for="chore in upcomingChores" :key="chore.id" class="flex justify-between items-center">
            <div class="neo-chore-info">
              <span class="neo-chore-name">{{ chore.name }}</span>
              <span class="neo-chore-due">{{ t('groupDetailPage.chores.duePrefix') }} {{ formatDate(chore.next_due_date) }}</span>
            </div>
            <VBadge :text="formatFrequency(chore.frequency)" :variant="getFrequencyBadgeVariant(chore.frequency)" />
          </VListItem>
        </VList>
        <div v-else class="text-center py-4">
          <VIcon name="cleaning_services" size="lg" class="opacity-50 mb-2" /> {/* Assuming cleaning_services is a valid VIcon name or will be added */}
          <p>{{ t('groupDetailPage.chores.emptyState') }}</p>
        </div>
      </VCard>

      <!-- Expenses Section -->
      <VCard class="mt-4">
        <template #header>
          <div class="flex justify-between items-center w-full">
            <VHeading level="3">{{ t('groupDetailPage.expenses.title') }}</VHeading>
            <VButton :to="`/groups/${groupId}/expenses`" variant="primary">
               <span class="material-icons" style="margin-right: 0.25em;">payments</span> {{ t('groupDetailPage.expenses.manageButton') }}
            </VButton>
          </div>
        </template>
        <VList v-if="recentExpenses.length > 0">
          <VListItem v-for="expense in recentExpenses" :key="expense.id" class="flex justify-between items-center">
            <div class="neo-expense-info">
              <span class="neo-expense-name">{{ expense.description }}</span>
              <span class="neo-expense-date">{{ formatDate(expense.expense_date) }}</span>
            </div>
            <div class="neo-expense-details">
              <span class="neo-expense-amount">{{ expense.currency }} {{ formatAmount(expense.total_amount) }}</span>
              <VBadge :text="formatSplitType(expense.split_type)" :variant="getSplitTypeBadgeVariant(expense.split_type)" />
            </div>
          </VListItem>
        </VList>
        <div v-else class="text-center py-4">
          <VIcon name="payments" size="lg" class="opacity-50 mb-2" /> {/* Assuming payments is a valid VIcon name or will be added */}
          <p>{{ t('groupDetailPage.expenses.emptyState') }}</p>
        </div>
      </VCard>

    </div>

    <VAlert v-else type="info" :message="t('groupDetailPage.groupNotFound')" />
  </main>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useI18n } from 'vue-i18n';
// import { useRoute } from 'vue-router';
import { apiClient, API_ENDPOINTS } from '@/config/api'; // Assuming path
import { useClipboard } from '@vueuse/core';
import ListsPage from './ListsPage.vue'; // Import ListsPage
import { useNotificationStore } from '@/stores/notifications';
import { choreService } from '../services/choreService'
import type { Chore, ChoreFrequency } from '../types/chore'
import { format } from 'date-fns'
import type { Expense } from '@/types/expense'
import VHeading from '@/components/valerie/VHeading.vue';
import VSpinner from '@/components/valerie/VSpinner.vue';
import VAlert from '@/components/valerie/VAlert.vue';
import VCard from '@/components/valerie/VCard.vue';
import VList from '@/components/valerie/VList.vue';
import VListItem from '@/components/valerie/VListItem.vue';
import VButton from '@/components/valerie/VButton.vue';
import VBadge from '@/components/valerie/VBadge.vue';
import VInput from '@/components/valerie/VInput.vue';
import VFormField from '@/components/valerie/VFormField.vue';
import VIcon from '@/components/valerie/VIcon.vue';

const { t } = useI18n();

interface Group {
  id: string | number;
  name: string;
  members?: GroupMember[];
}

interface GroupMember {
  id: number;
  email: string;
  role?: string;
}

const props = defineProps<{
  id: string;
}>();

// const route = useRoute();
// const $q = useQuasar(); // Not used anymore

const notificationStore = useNotificationStore();
const group = ref<Group | null>(null);
const loading = ref(true);
const error = ref<string | null>(null);
const inviteCode = ref<string | null>(null);
const inviteExpiresAt = ref<string | null>(null);
const generatingInvite = ref(false);
const copySuccess = ref(false);
const removingMember = ref<number | null>(null);

// groupId is directly from props.id now, which comes from the route path param
const groupId = computed(() => props.id);

const { copy, copied, isSupported: clipboardIsSupported } = useClipboard({
  source: computed(() => inviteCode.value || '')
});

// Chores state
const upcomingChores = ref<Chore[]>([])

// Add new state for expenses
const recentExpenses = ref<Expense[]>([])

const fetchActiveInviteCode = async () => {
  if (!groupId.value) return;
  // Consider adding a loading state for this fetch if needed, e.g., initialInviteCodeLoading
  try {
    const response = await apiClient.get(API_ENDPOINTS.GROUPS.GET_ACTIVE_INVITE(String(groupId.value)));
    if (response.data && response.data.code) {
      inviteCode.value = response.data.code;
      inviteExpiresAt.value = response.data.expires_at; // Store expiry
    } else {
      inviteCode.value = null; // No active code found
      inviteExpiresAt.value = null;
    }
  } catch (err: any) {
    if (err.response && err.response.status === 404) {
      inviteCode.value = null; // Explicitly set to null on 404
      inviteExpiresAt.value = null;
      // Optional: notify user or set a flag to show "generate one" message more prominently
      console.info('No active invite code found for this group.');
    } else {
      const message = err instanceof Error ? err.message : 'Failed to fetch active invite code.';
      // error.value = message; // This would display a large error banner, might be too much
      console.error('Error fetching active invite code:', err);
      notificationStore.addNotification({ message, type: 'error' });
    }
  }
};

const fetchGroupDetails = async () => {
  if (!groupId.value) return;
  loading.value = true;
  error.value = null;
  try {
    const response = await apiClient.get(API_ENDPOINTS.GROUPS.BY_ID(String(groupId.value)));
    group.value = response.data;
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : 'Failed to fetch group details.';
    error.value = message;
    console.error('Error fetching group details:', err);
    notificationStore.addNotification({ message, type: 'error' });
  } finally {
    loading.value = false;
  }
  // Fetch active invite code after group details are loaded
  await fetchActiveInviteCode();
};

const generateInviteCode = async () => {
  if (!groupId.value) return;
  generatingInvite.value = true;
  copySuccess.value = false;
  try {
    const response = await apiClient.post(API_ENDPOINTS.GROUPS.CREATE_INVITE(String(groupId.value)));
    if (response.data && response.data.code) {
      inviteCode.value = response.data.code;
      inviteExpiresAt.value = response.data.expires_at; // Update with new expiry
        notificationStore.addNotification({ message: t('groupDetailPage.notifications.generateInviteSuccess'), type: 'success' });
    } else {
      // Should not happen if POST is successful and returns the code
        throw new Error(t('groupDetailPage.invites.errors.newDataInvalid'));
    }
  } catch (err: unknown) {
      const message = err instanceof Error ? err.message : t('groupDetailPage.notifications.generateInviteError');
    console.error('Error generating invite code:', err);
    notificationStore.addNotification({ message, type: 'error' });
  } finally {
    generatingInvite.value = false;
  }
};

const copyInviteCodeHandler = async () => {
  if (!clipboardIsSupported.value || !inviteCode.value) {
      notificationStore.addNotification({ message: t('groupDetailPage.notifications.clipboardNotSupported'), type: 'warning' });
    return;
  }
  await copy(inviteCode.value);
  if (copied.value) {
    copySuccess.value = true;
    setTimeout(() => (copySuccess.value = false), 2000);
    // Optionally, notify success via store if preferred over inline message
    // notificationStore.addNotification({ message: 'Invite code copied!', type: 'info' });
  } else {
      notificationStore.addNotification({ message: t('groupDetailPage.notifications.copyInviteFailed'), type: 'error' });
  }
};

const canRemoveMember = (member: GroupMember): boolean => {
  // Only allow removing members if the current user is the owner
  // and the member is not the owner themselves
  return group.value?.members?.some(m => m.role === 'owner' && m.id === member.id) === false;
};

const removeMember = async (memberId: number) => {
  if (!groupId.value) return;

  removingMember.value = memberId;
  try {
    await apiClient.delete(API_ENDPOINTS.GROUPS.MEMBER(String(groupId.value), String(memberId)));
    // Refresh group details to update the members list
    await fetchGroupDetails();
    notificationStore.addNotification({
      message: t('groupDetailPage.notifications.removeMemberSuccess'),
      type: 'success'
    });
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : t('groupDetailPage.notifications.removeMemberFailed');
    console.error('Error removing member:', err);
    notificationStore.addNotification({ message, type: 'error' });
  } finally {
    removingMember.value = null;
  }
};

// Chores methods
const loadUpcomingChores = async () => {
  if (!groupId.value) return
  try {
    const chores = await choreService.getChores(Number(groupId.value))
    // Sort by due date and take the next 5
    upcomingChores.value = chores
      .sort((a, b) => new Date(a.next_due_date).getTime() - new Date(b.next_due_date).getTime())
      .slice(0, 5)
  } catch (error) {
    console.error('Error loading upcoming chores:', error)
  }
}

const formatDate = (date: string) => {
  return format(new Date(date), 'MMM d, yyyy')
}

const formatFrequency = (frequency: ChoreFrequency) => {
  const options: Record<ChoreFrequency, string> = {
    one_time: t('choresPage.frequencyOptions.oneTime'), // Reusing existing keys
    daily: t('choresPage.frequencyOptions.daily'),
    weekly: t('choresPage.frequencyOptions.weekly'),
    monthly: t('choresPage.frequencyOptions.monthly'),
    custom: t('choresPage.frequencyOptions.custom')
  };
  return options[frequency] || frequency;
};

const getFrequencyBadgeVariant = (frequency: ChoreFrequency): string => {
  const colorMap: Record<ChoreFrequency, string> = {
    one_time: 'neutral',
    daily: 'info',
    weekly: 'success',
    monthly: 'accent', // Using accent for purple as an example
    custom: 'warning'
  };
  return colorMap[frequency] || 'secondary';
};

// Add new methods for expenses
const loadRecentExpenses = async () => {
  if (!groupId.value) return
  try {
    const response = await apiClient.get(`/api/groups/${groupId.value}/expenses`)
    recentExpenses.value = response.data.slice(0, 5) // Get only the 5 most recent expenses
  } catch (error) {
    console.error('Error loading recent expenses:', error)
  }
}

const formatAmount = (amount: string) => {
  return parseFloat(amount).toFixed(2)
}

const formatSplitType = (type: string) => {
  // Assuming 'type' is like 'exact_amounts' or 'item_based'
  const key = `groupDetailPage.expenses.splitTypes.${type.toLowerCase().replace(/_([a-z])/g, g => g[1].toUpperCase())}`;
  // This creates keys like 'groupDetailPage.expenses.splitTypes.exactAmounts'
  // Check if translation exists, otherwise fallback to a simple formatted string
  // For simplicity in this subtask, we'll assume keys will be added.
  // A more robust solution would check i18n.global.te(key) or have a fallback.
  return t(key);
};

const getSplitTypeBadgeVariant = (type: string): string => {
  const colorMap: Record<string, string> = {
    equal: 'info',
    exact_amounts: 'success',
    percentage: 'accent', // Using accent for purple
    shares: 'warning',
    item_based: 'secondary', // Using secondary for teal as an example
  };
  return colorMap[type] || 'neutral';
};

onMounted(() => {
  fetchGroupDetails();
  loadUpcomingChores();
  loadRecentExpenses();
});
</script>

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

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

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

.mt-3 {
  margin-top: 1.5rem;
}

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

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

.ml-1 {
  margin-left: 0.25rem;
}

.w-full {
  width: 100%;
}

/* Neo Grid Layout */
.neo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  margin-bottom: 2rem;
}

/* Neo Card Styles */
.neo-card {
  border-radius: 18px;
  box-shadow: 6px 6px 0 #111;
  background: var(--light);
  border: 3px solid #111;
  overflow: hidden;
}

.neo-card-header {
  padding: 1.5rem;
  border-bottom: 3px solid #111;
  background: #fafafa;
}

.neo-card-header h3 {
  font-weight: 900;
  font-size: 1.25rem;
  margin: 0;
  letter-spacing: 0.5px;
}

.neo-card-body {
  padding: 1.5rem;
}

/* Members List Styles */
.neo-members-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.neo-member-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  border-radius: 12px;
  background: #fafafa;
  border: 2px solid #111;
  transition: transform 0.1s ease-in-out;
}

.neo-member-item:hover {
  transform: translateY(-2px);
}

.neo-member-info {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.neo-member-name {
  font-weight: 600;
  font-size: 1.1rem;
}

.neo-member-role {
  font-size: 0.875rem;
  padding: 0.25rem 0.75rem;
  border-radius: 1rem;
  background: #e0e0e0;
  font-weight: 600;
}

.neo-member-role.owner {
  background: #111;
  color: white;
}

/* Invite Code Styles */
.neo-invite-code {
  background: #fafafa;
  padding: 1rem;
  border-radius: 12px;
  border: 2px solid #111;
}

.neo-label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.neo-input-group {
  display: flex;
  gap: 0.5rem;
}

.neo-input {
  flex: 1;
  padding: 0.75rem;
  border: 2px solid #111;
  border-radius: 8px;
  font-family: monospace;
  font-size: 1rem;
  background: white;
}

.neo-success-text {
  color: var(--success);
  font-size: 0.9rem;
  font-weight: 600;
  margin-top: 0.5rem;
}

/* Empty State Styles */
.neo-empty-state {
  text-align: center;
  padding: 2rem;
  color: #666;
}

.neo-empty-state .icon {
  width: 3rem;
  height: 3rem;
  margin-bottom: 1rem;
  opacity: 0.5;
}

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

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

  .neo-card-header,
  .neo-card-body {
    padding: 1rem;
  }

  .neo-member-item {
    flex-direction: column;
    gap: 0.75rem;
    align-items: flex-start;
  }

  .neo-member-info {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
  }
}

/* Chores List Styles */
.neo-chores-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.neo-chore-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  border-radius: 12px;
  background: #fafafa;
  border: 2px solid #111;
  transition: transform 0.1s ease-in-out;
}

.neo-chore-item:hover {
  transform: translateY(-2px);
}

.neo-chore-info {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.neo-chore-name {
  font-weight: 600;
  font-size: 1.1rem;
}

.neo-chore-due {
  font-size: 0.875rem;
  color: #666;
}

/* Expenses List Styles */
.neo-expenses-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.neo-expense-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  border-radius: 12px;
  background: #fafafa;
  border: 2px solid #111;
  transition: transform 0.1s ease-in-out;
}

.neo-expense-item:hover {
  transform: translateY(-2px);
}

.neo-expense-info {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.neo-expense-name {
  font-weight: 600;
  font-size: 1.1rem;
}

.neo-expense-date {
  font-size: 0.875rem;
  color: #666;
}

.neo-expense-details {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.neo-expense-amount {
  font-weight: 600;
  font-size: 1.1rem;
}

.neo-chip {
  padding: 0.25rem 0.75rem;
  border-radius: 1rem;
  font-size: 0.875rem;
  font-weight: 600;
  background: #e0e0e0;
}

.neo-chip.blue {
  background: #e3f2fd;
  color: #1976d2;
}

.neo-chip.green {
  background: #e8f5e9;
  color: #2e7d32;
}

.neo-chip.purple {
  background: #f3e5f5;
  color: #7b1fa2;
}

.neo-chip.orange {
  background: #fff3e0;
  color: #f57c00;
}

.neo-chip.teal {
  background: #e0f2f1;
  color: #00796b;
}

.neo-chip.grey {
  background: #f5f5f5;
  color: #616161;
}
</style>
