<template>
  <div class="admin-member-detail">
    <!-- Page Header -->
    <div class="page-header">
      <div class="header-nav">
        <NuxtLink to="/admin/members" class="back-link">← Members</NuxtLink>
        <NuxtLink v-if="member && member.status === 'active' && member.showInDirectory" :to="`/members/${member._id}`" class="profile-link" target="_blank">
          View public profile ↗
        </NuxtLink>
      </div>
      <div class="header-row">
        <div>
          <h1 v-if="member">{{ member.name }}</h1>
          <h1 v-else-if="pending">Loading…</h1>
          <h1 v-else>Member not found</h1>
          <p v-if="member" class="member-email">{{ member.email }}</p>
        </div>
        <div v-if="member" class="header-badges">
          <span class="badge" :class="member.circle">{{ member.circle }}</span>
          <span :class="statusClass(member.status)" class="status-badge">{{ member.status }}</span>
        </div>
      </div>
    </div>

    <div v-if="pending" class="loading-state">
      <div class="spinner" />
      Loading member…
    </div>

    <div v-else-if="fetchError" class="error-state">Failed to load member.</div>

    <template v-else-if="member">
      <div class="detail-body">
        <!-- LEFT COLUMN: form + metadata -->
        <div class="detail-left">
          <!-- Edit form -->
          <section class="detail-section">
            <div class="section-label">Member details</div>
            <form class="edit-form" @submit.prevent="submitEdit">
              <div class="field">
                <label>Name</label>
                <input v-model="form.name" type="text" required >
              </div>
              <div class="field">
                <label>Email</label>
                <input v-model="form.email" type="email" required >
              </div>
              <div class="field">
                <label>Circle</label>
                <select v-model="form.circle">
                  <option value="community">Community</option>
                  <option value="founder">Founder</option>
                  <option value="practitioner">Practitioner</option>
                </select>
              </div>
              <div class="field">
                <label>Contribution ($/mo)</label>
                <input v-model.number="form.contributionAmount" type="number" min="0" step="1">
                <p class="field-hint field-hint--warn">
                  Writes to our database only. If the member is on a paid plan, also update <code>recurringAmount</code> in the Helcim dashboard — this form does not sync.
                </p>
              </div>
              <div class="field">
                <label>Status</label>
                <select v-model="form.status">
                  <option value="pending_payment">pending_payment</option>
                  <option value="active">active</option>
                  <option value="suspended">suspended</option>
                  <option value="cancelled">cancelled</option>
                </select>
              </div>
              <div class="field">
                <label>Role</label>
                <select v-model="form.role">
                  <option value="member">member</option>
                  <option value="admin">admin</option>
                </select>
              </div>
              <div class="form-actions">
                <button type="submit" class="btn btn-primary" :disabled="saving">
                  {{ saving ? "Saving…" : "Save changes" }}
                </button>
                <button type="button" class="btn" @click="resetForm">Reset</button>
              </div>
            </form>
          </section>

          <!-- Metadata -->
          <section class="detail-section">
            <div class="section-label">Account info</div>
            <dl class="meta-list">
              <div v-if="member.memberNumber" class="meta-row">
                <dt>Member number</dt>
                <dd class="mono">#{{ member.memberNumber }}</dd>
              </div>
              <div class="meta-row">
                <dt>Member ID</dt>
                <dd class="mono">{{ member._id }}</dd>
              </div>
              <div class="meta-row">
                <dt>Joined</dt>
                <dd>{{ formatDate(member.createdAt) }}</dd>
              </div>
              <div class="meta-row">
                <dt>Invite email</dt>
                <dd :class="member.inviteEmailSent ? 'status-ok' : 'status-dim'">
                  {{ member.inviteEmailSent ? "Sent" : "Not sent" }}
                </dd>
              </div>
              <div class="meta-row">
                <dt>Slack invite</dt>
                <dd v-if="member.slackInvited" class="status-ok">
                  Invited {{ formatDate(member.slackInvitedAt) }}
                </dd>
                <dd v-else class="meta-action">
                  <span class="status-dim">Not yet invited</span>
                  <button
                    type="button"
                    class="link-btn"
                    :disabled="markingSlackInvited"
                    @click="markSlackInvited"
                  >
                    {{ markingSlackInvited ? "Marking…" : "Mark as Slack invited" }}
                  </button>
                </dd>
              </div>
              <div v-if="member.helcimCustomerId" class="meta-row">
                <dt>Helcim customer</dt>
                <dd class="mono">{{ member.helcimCustomerId }}</dd>
              </div>
              <div v-if="member.helcimSubscriptionId" class="meta-row">
                <dt>Helcim subscription</dt>
                <dd class="mono">{{ member.helcimSubscriptionId }}</dd>
              </div>
            </dl>
          </section>

          <!-- Onboarding -->
          <section class="detail-section">
            <div class="section-label">Onboarding</div>
            <dl class="meta-list">
              <div class="meta-row">
                <dt>Profile Tags</dt>
                <dd :class="hasProfileTags ? 'status-ok' : 'status-dim'">
                  {{ hasProfileTags ? '✓ Complete' : '— Incomplete' }}
                </dd>
              </div>
              <div class="meta-row">
                <dt>Event Page Visited</dt>
                <dd :class="member.onboarding?.eventPageVisited ? 'status-ok' : 'status-dim'">
                  {{ member.onboarding?.eventPageVisited ? '✓ Complete' : '— Incomplete' }}
                </dd>
              </div>
              <div class="meta-row">
                <dt>Board Engaged</dt>
                <dd :class="hasBoardEngaged ? 'status-ok' : 'status-dim'">
                  {{ hasBoardEngaged ? '✓ Complete' : '— Incomplete' }}
                </dd>
              </div>
              <div class="meta-row">
                <dt>Wiki Clicked</dt>
                <dd :class="member.onboarding?.wikiClicked ? 'status-ok' : 'status-dim'">
                  {{ member.onboarding?.wikiClicked ? '✓ Complete' : '— Incomplete' }}
                </dd>
              </div>
              <div class="meta-row">
                <dt>Completed</dt>
                <dd :class="member.onboarding?.completedAt ? 'status-ok' : 'status-dim'">
                  {{ member.onboarding?.completedAt ? formatDate(member.onboarding.completedAt) : 'In progress' }}
                </dd>
              </div>
            </dl>
          </section>

          <!-- Notification preferences -->
          <section class="detail-section">
            <div class="section-label">Notification preferences</div>
            <dl class="meta-list">
              <div class="meta-row">
                <dt>Event reminders</dt>
                <dd :class="member.notifications?.events !== false ? 'status-ok' : 'status-dim'">
                  {{ member.notifications?.events !== false ? "On" : "Off" }}
                </dd>
              </div>
              <div class="meta-row">
                <dt>Community updates</dt>
                <dd :class="member.notifications?.updates !== false ? 'status-ok' : 'status-dim'">
                  {{ member.notifications?.updates !== false ? "On" : "Off" }}
                </dd>
              </div>
            </dl>
          </section>
        </div>

        <!-- RIGHT COLUMN: activity log -->
        <div class="detail-right">
          <div class="activity-panel">
            <div class="activity-panel-header">
              <div class="section-label">Activity log</div>
              <span class="activity-legend">
                <span class="al-vis-badge">admin-only</span> = not visible to member
              </span>
            </div>
            <ClientOnly>
              <div v-if="activityLoading && !activityEntries.length" class="activity-loading">
                <div class="spinner" />
                Loading activity...
              </div>
              <div v-else-if="activityEntries.length" class="activity-timeline">
                <div
                  v-for="entry in activityEntries"
                  :key="entry._id"
                  class="al-item"
                  :class="{ 'al-admin': entry.visibility === 'admin' }"
                >
                  <div class="al-dot" />
                  <div class="al-body">
                    <div class="al-row">
                      <UIcon :name="getActivity(entry).icon" class="al-icon" />
                      <span class="al-text">{{ getActivity(entry).text }}</span>
                      <span v-if="entry.visibility === 'admin'" class="al-vis-badge">admin-only</span>
                    </div>
                    <span class="al-time">{{ formatDate(entry.timestamp) }}</span>
                  </div>
                </div>
                <div v-if="activityHasMore" class="al-load-more">
                  <button class="btn" :disabled="activityLoadingMore" @click="loadMoreActivity">
                    {{ activityLoadingMore ? 'Loading...' : 'Load more' }}
                  </button>
                </div>
              </div>
              <div v-else class="activity-empty">
                No activity recorded.
              </div>
            </ClientOnly>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<script setup>
import { formatActivity } from '~/utils/activityText'

definePageMeta({
  layout: "admin",
  middleware: "admin",
});

const route = useRoute();
const toast = useToast();

const {
  data: member,
  pending,
  error: fetchError,
} = await useFetch(`/api/admin/members/${route.params.id}`);

const pageBreadcrumbTitle = useState("pageBreadcrumbTitle", () => "");
pageBreadcrumbTitle.value = member.value?.name || "";

watch(member, (val) => {
  pageBreadcrumbTitle.value = val?.name || "";
});

onUnmounted(() => {
  pageBreadcrumbTitle.value = "";
});

const form = reactive({
  name: "",
  email: "",
  circle: "",
  contributionAmount: 0,
  status: "",
  role: "",
});

const saving = ref(false);

function populateForm(m) {
  if (!m) return;
  form.name = m.name;
  form.email = m.email;
  form.circle = m.circle;
  form.contributionAmount = m.contributionAmount ?? 0;
  form.status = m.status || "pending_payment";
  form.role = m.role || "member";
}

// Populate once data is ready
if (member.value) populateForm(member.value);
watch(member, populateForm, { immediate: false });

function resetForm() {
  populateForm(member.value);
}

async function submitEdit() {
  saving.value = true;
  try {
    const updated = await $fetch(`/api/admin/members/${route.params.id}`, {
      method: "PUT",
      body: {
        name: form.name,
        email: form.email,
        circle: form.circle,
        contributionAmount: form.contributionAmount,
        status: form.status,
      },
    });
    // Update role separately if it changed
    if (form.role !== member.value?.role) {
      await $fetch(`/api/admin/members/${route.params.id}/role`, {
        method: "PATCH",
        body: { role: form.role },
      });
    }
    // Reflect changes locally
    if (member.value) {
      member.value = { ...member.value, ...updated, role: form.role };
      pageBreadcrumbTitle.value = form.name;
    }
    toast.add({ title: "Member updated", color: "success" });
  } catch (err) {
    toast.add({
      title: "Failed to update member",
      description: err.data?.statusMessage || err.message,
      color: "error",
    });
  } finally {
    saving.value = false;
  }
}

function formatDate(val) {
  if (!val) return "—";
  return new Date(val).toLocaleDateString("en-US", {
    year: "numeric",
    month: "short",
    day: "numeric",
  });
}

function statusClass(status) {
  if (status === "active") return "status-ok";
  if (status === "cancelled" || status === "suspended") return "status-error";
  return "status-dim";
}

// Onboarding computed states
const hasProfileTags = computed(() => {
  const m = member.value
  if (!m) return false
  return m.craftTags?.length > 0 && m.board?.topics?.length > 0
})

const hasBoardEngaged = computed(() => {
  const m = member.value
  if (!m) return false
  return m.onboarding?.boardPageVisited && m.board?.topics?.some(
    t => ['help', 'interested', 'seeking'].includes(t.state)
  )
})

const markingSlackInvited = ref(false)

async function markSlackInvited() {
  if (!member.value || markingSlackInvited.value) return
  markingSlackInvited.value = true
  try {
    const res = await $fetch(
      `/api/admin/members/${route.params.id}/slack-status`,
      {
        method: "PATCH",
        body: { slackInvited: true },
      },
    )
    member.value = { ...member.value, ...res.member }
    toast.add({ title: "Marked as Slack invited", color: "success" })
  } catch (err) {
    toast.add({
      title: "Failed to mark Slack invited",
      description: err.data?.statusMessage || err.message,
      color: "error",
    })
  } finally {
    markingSlackInvited.value = false
  }
}

// Activity log
const activityEntries = ref([])
const activityLoading = ref(false)
const activityLoadingMore = ref(false)
const activityHasMore = ref(false)
const activityNextCursor = ref(null)

const getActivity = (entry) => formatActivity(entry)

async function loadActivity() {
  activityLoading.value = true
  try {
    const data = await $fetch(`/api/admin/members/${route.params.id}/activity`, {
      params: { limit: 20 }
    })
    activityEntries.value = data.entries
    activityHasMore.value = data.hasMore
    activityNextCursor.value = data.nextCursor
  } catch (err) {
    console.error('Failed to load activity:', err)
  } finally {
    activityLoading.value = false
  }
}

async function loadMoreActivity() {
  if (!activityNextCursor.value) return
  activityLoadingMore.value = true
  try {
    const data = await $fetch(`/api/admin/members/${route.params.id}/activity`, {
      params: { limit: 20, before: activityNextCursor.value }
    })
    activityEntries.value.push(...data.entries)
    activityHasMore.value = data.hasMore
    activityNextCursor.value = data.nextCursor
  } catch (err) {
    console.error('Failed to load more activity:', err)
  } finally {
    activityLoadingMore.value = false
  }
}

onMounted(loadActivity)
</script>

<style scoped>
.admin-member-detail {}

/* ---- PAGE HEADER ---- */
.page-header {
  padding: 28px 28px 20px;
  border-bottom: 1px dashed var(--border);
}

.header-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.back-link {
  font-size: 11px;
  color: var(--text-faint);
  text-decoration: none;
  letter-spacing: 0.02em;
}

.back-link:hover {
  color: var(--candle);
  text-decoration: none;
}

.profile-link {
  font-size: 11px;
  color: var(--candle);
  text-decoration: none;
  letter-spacing: 0.02em;
}

.profile-link:hover {
  text-decoration: underline;
}

.header-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.page-header h1 {
  font-family: "Brygada 1918", serif;
  font-size: 24px;
  font-weight: 500;
  color: var(--text-bright);
  margin: 0 0 4px;
  line-height: 1.2;
}

.member-email {
  font-size: 12px;
  color: var(--text-faint);
  margin: 0;
}

.header-badges {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding-top: 4px;
}

.status-badge {
  font-size: 10px;
  font-family: "Commit Mono", monospace;
  padding: 2px 8px;
  border: 1px dashed var(--border);
  color: var(--text-dim);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ---- TWO-COLUMN BODY ---- */
.detail-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  min-height: 0;
}

.detail-left {
  border-right: 1px dashed var(--border);
}

.detail-section {
  padding: 24px 28px;
  border-bottom: 1px dashed var(--border);
}

.edit-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 12px;
}

.field-hint {
  font-size: 11px;
  color: var(--text-faint);
  margin: 6px 0 0;
  line-height: 1.4;
}

.field-hint--warn {
  color: var(--ember);
  border-left: 2px solid var(--ember);
  padding: 4px 0 4px 8px;
}

.field-hint code {
  font-family: "Commit Mono", monospace;
  font-size: 10px;
}

.form-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
  padding-top: 16px;
  border-top: 1px dashed var(--border);
}

.meta-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: 1px dashed var(--border);
  margin-top: 12px;
}

.meta-row {
  display: flex;
  gap: 16px;
  padding: 9px 14px;
  border-bottom: 1px dashed var(--border);
}

.meta-row:last-child {
  border-bottom: none;
}

.meta-row dt {
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.02em;
  min-width: 140px;
  flex-shrink: 0;
  padding-top: 1px;
}

.meta-row dd {
  font-size: 12px;
  color: var(--text);
  margin: 0;
  word-break: break-all;
}

.meta-action {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.link-btn {
  background: none;
  border: none;
  color: var(--candle);
  cursor: pointer;
  font-family: "Commit Mono", monospace;
  font-size: 11px;
  padding: 2px 6px;
}

.link-btn:hover {
  text-decoration: underline;
}

.link-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.mono {
  font-family: "Commit Mono", monospace;
  font-size: 11px;
}

/* ---- STATUS ---- */
.status-ok {
  color: var(--green);
}

.status-dim {
  color: var(--text-faint);
}

.status-error {
  color: var(--ember);
}

/* ---- STATES ---- */
.loading-state,
.error-state {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text-dim);
  font-size: 13px;
  padding: 40px 28px;
}

.spinner {
  width: 16px;
  height: 16px;
  border: 2px dashed var(--candle);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  flex-shrink: 0;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ---- ACTIVITY PANEL ---- */
.detail-right {
  position: relative;
}

.activity-panel {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 120px);
}

.activity-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24px 28px 16px;
  border-bottom: 1px dashed var(--border);
  flex-shrink: 0;
}

.activity-legend {
  font-size: 10px;
  color: var(--text-faint);
  display: flex;
  align-items: center;
  gap: 6px;
}

.activity-loading {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 32px 28px;
  color: var(--text-faint);
  font-size: 12px;
}

.activity-empty {
  padding: 32px 28px;
  color: var(--text-faint);
  font-size: 12px;
}

/* Timeline */
.activity-timeline {
  overflow-y: auto;
  flex: 1;
  padding: 16px 0 24px;
}

.al-item {
  display: grid;
  grid-template-columns: 20px 1fr;
  gap: 0 10px;
  padding: 0 28px 0 20px;
  margin-bottom: 16px;
  position: relative;
}

.al-item::before {
  content: '';
  position: absolute;
  left: 27px;
  top: 18px;
  bottom: -16px;
  width: 1px;
  border-left: 1px dashed var(--border);
}

.al-item:last-child::before {
  display: none;
}

.al-dot {
  width: 6px;
  height: 6px;
  border: 1px dashed var(--border);
  background: var(--bg);
  flex-shrink: 0;
  margin-top: 4px;
  align-self: start;
}

.al-admin .al-dot {
  border-color: var(--candle-faint);
  background: var(--surface);
}

.al-body {
  min-width: 0;
}

.al-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  flex-wrap: wrap;
}

.al-icon {
  width: 14px;
  height: 14px;
  color: var(--text-faint);
  flex-shrink: 0;
  margin-top: 1px;
}

.al-text {
  flex: 1;
  min-width: 0;
  color: var(--text);
  font-size: 12px;
  line-height: 1.4;
}

.al-time {
  display: block;
  color: var(--text-faint);
  font-size: 10px;
  margin-top: 3px;
  letter-spacing: 0.02em;
}

.al-vis-badge {
  font-size: 9px;
  color: var(--candle);
  border: 1px dashed var(--candle-faint);
  padding: 1px 5px;
  flex-shrink: 0;
  letter-spacing: 0.04em;
}

.al-load-more {
  display: flex;
  justify-content: center;
  padding: 8px 28px 0;
}

/* ---- RESPONSIVE ---- */
@media (max-width: 1024px) {
  .detail-body {
    grid-template-columns: 1fr;
  }

  .detail-left {
    border-right: none;
  }

  .activity-panel {
    position: static;
    max-height: none;
    border-top: 1px dashed var(--border);
  }
}

@media (max-width: 768px) {
  .page-header {
    padding: 24px 20px 16px;
  }

  .detail-section {
    padding: 20px;
  }

  .activity-panel-header {
    padding: 16px 20px 12px;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .al-item {
    padding: 0 20px 0 14px;
  }

  .meta-row {
    flex-direction: column;
    gap: 4px;
  }

  .meta-row dt {
    min-width: unset;
  }
}
</style>
