<template>
  <PageShell as="form" @submit.prevent="handleSubmit">
    <ClientOnly>
      <div v-if="loading" class="loading-state">
        <p style="color: var(--text-faint)">Loading your profile...</p>
      </div>

      <div v-else-if="!memberData" class="loading-state">
        <p style="color: var(--text-faint); margin-bottom: 12px">
          Please sign in to access your profile settings.
        </p>
        <button
          type="button"
          class="btn btn-primary"
          @click="
            openLoginModal({
              title: 'Sign in to your profile',
              description: 'Enter your email to manage your profile settings',
            })
          "
        >
          Sign In
        </button>
      </div>

      <template v-else>
        <!-- PAGE HEADER -->
        <PageHeader title="Edit Profile">
          <NuxtLink
            v-if="
              memberId &&
              memberData?.status === MEMBER_STATUSES.ACTIVE &&
              formData.showInDirectory
            "
            :to="`/members/${memberId}`"
            class="view-profile-link"
          >
            View my public profile &rarr;
          </NuxtLink>
        </PageHeader>

        <ColumnsLayout cols="2">
          <template #left>
            <PageSection>
              <div class="section-label">Basics</div>

              <div class="field">
                <label>Name</label>
                <input
                  v-model="formData.name"
                  type="text"
                  placeholder="Your name"
                  required
                >
              </div>

              <div class="field">
                <label>Pronouns</label>
                <input
                  v-model="formData.pronouns"
                  type="text"
                  placeholder="e.g., she/her, they/them"
                >
              </div>
              <div class="field">
                <label>Timezone</label>
                <USelectMenu
                  v-model="formData.timeZone"
                  :items="timezoneItems"
                  value-key="value"
                  searchable
                  searchable-placeholder="Search timezones..."
                  placeholder="Select a timezone"
                  class="timezone-select"
                  :ui="{
                    content: 'tz-content',
                    item: 'tz-item',
                    input: 'tz-input',
                  }"
                />
              </div>

              <div class="field">
                <label>Avatar</label>
                <div class="avatar-row">
                  <button
                    v-for="ghost in availableGhosts"
                    :key="ghost.value"
                    type="button"
                    class="avatar-option"
                    :class="{ selected: formData.avatar === ghost.value }"
                    :title="ghost.label"
                    @click="formData.avatar = ghost.value"
                  >
                    <img :src="ghost.image" :alt="ghost.label" >
                  </button>
                </div>
              </div>
            </PageSection>

            <PageSection divider="top">
              <div class="section-label">About You</div>

              <div class="row-2">
                <div class="field">
                  <label>Studio / Organization</label>
                  <input
                    v-model="formData.studio"
                    type="text"
                    placeholder="Studio name"
                  >
                </div>
                <div class="field">
                  <label>Location</label>
                  <input
                    v-model="formData.location"
                    type="text"
                    placeholder="Toronto, ON"
                  >
                </div>
              </div>

              <div class="field">
                <label>Bio</label>
                <textarea
                  v-model="formData.bio"
                  rows="4"
                  placeholder="Share your background, interests, and experience..."
                  maxlength="300"
                />
                <div class="char-count">
                  {{ formData.bio?.length || 0 }} / 300
                </div>
              </div>

              <div class="field">
                <label>What I Do</label>
                <CraftTagSelector
                  v-model="formData.craftTags"
                  :tags="craftTags"
                  @suggest="openTagSuggest('craft')"
                />
              </div>
            </PageSection>

            <PageSection divider="top">
              <div class="section-label">Visibility</div>

              <div class="toggle-field">
                <USwitch
                  v-model="formData.showInDirectory"
                  aria-label="Show in Member Directory"
                />
                <div class="toggle-label">
                  Show in Member Directory
                  <span class="toggle-sub"
                    >Your profile will appear in the private member
                    directory.</span
                  >
                </div>
              </div>
            </PageSection>
          </template>

          <template #right>
            <PageSection>
              <div class="section-label">Board</div>

              <div class="field">
                <label>Gamma Space Slack Handle</label>
                <input
                  v-model="formData.boardSlackHandle"
                  type="text"
                  placeholder="@yourslackname"
                >
                <div class="field-help">
                  Shown on your board posts so other members can reach out.
                </div>
              </div>

              <div class="posts-header">
                <div class="posts-heading">Your Posts</div>
                <NuxtLink to="/board" class="posts-new-link"
                  >+ New Post</NuxtLink
                >
              </div>

              <div v-if="myPosts.length === 0" class="posts-empty">
                No posts yet.
                <NuxtLink to="/board" class="posts-empty-link">
                  Visit the Board
                </NuxtLink>
                to share what you're seeking or offering.
              </div>

              <ul v-else class="posts-list">
                <li v-for="post in myPosts" :key="post._id" class="post-item">
                  <div class="post-body">
                    <div class="post-title">{{ post.title }}</div>
                    <div class="post-excerpt">{{ postExcerpt(post) }}</div>
                  </div>
                  <div class="post-actions">
                    <NuxtLink to="/board" class="post-action">Edit</NuxtLink>
                    <button
                      type="button"
                      class="post-action post-action-danger"
                      @click="handleDeletePost(post)"
                    >
                      Delete
                    </button>
                  </div>
                </li>
              </ul>
            </PageSection>

            <PageSection divider="top">
              <div class="section-label">Notifications</div>

              <div
                v-for="toggle in notificationToggles"
                :key="toggle.key"
                class="toggle-field"
              >
                <USwitch
                  v-model="formData.notifications[toggle.key]"
                  :aria-label="toggle.label"
                />
                <div class="toggle-label">
                  {{ toggle.label }}
                  <span class="toggle-sub">{{ toggle.sub }}</span>
                </div>
              </div>
            </PageSection>

            <PageSection divider="top">
              <div class="section-label">Recent Activity</div>

              <div v-if="activityLoading" class="activity-empty">
                Loading activity…
              </div>
              <ul v-else-if="recentActivity.length" class="activity-list">
                <li
                  v-for="entry in recentActivity"
                  :key="entry._id"
                  class="activity-item"
                >
                  <div class="activity-time">
                    {{ formatActivityTime(entry.timestamp) }}
                  </div>
                  <div class="activity-text">
                    <template v-if="formatActivity(entry).link">
                      <span>{{
                        formatActivity(entry).text.split(
                          formatActivity(entry).linkText,
                        )[0]
                      }}</span>
                      <NuxtLink
                        :to="formatActivity(entry).link"
                        class="activity-link"
                      >
                        {{ formatActivity(entry).linkText }}
                      </NuxtLink>
                    </template>
                    <span v-else>{{ formatActivity(entry).text }}</span>
                  </div>
                </li>
              </ul>
              <div v-else class="activity-empty">
                Your activity will appear here as you use the Guild.
              </div>
            </PageSection>
          </template>
        </ColumnsLayout>

        <!-- ======== SAVE BAR ======== -->
        <div class="save-bar">
          <button
            type="submit"
            class="btn btn-primary"
            :disabled="saving || !hasChanges"
          >
            {{ saving ? "Saving..." : "Save Profile" }}
          </button>
          <button type="button" class="btn" @click="resetForm">
            Reset Changes
          </button>
        </div>
      </template>

      <template #fallback>
        <div class="loading-state">
          <p style="color: var(--text-faint)">Loading your profile...</p>
        </div>
      </template>
    </ClientOnly>

    <TagSuggestModal
      v-model:open="showTagSuggestModal"
      :pool="tagSuggestPool"
    />
  </PageShell>
</template>

<script setup>
import { MEMBER_STATUSES } from "~/composables/useMemberStatus";
import { TIMEZONE_OPTIONS } from "~/config/timezones";
import { formatActivity } from "~/utils/activityText";

definePageMeta({
  middleware: "auth",
});

const { memberData, checkMemberStatus } = useAuth();
const { openLoginModal } = useLoginModal();
const { posts: myPosts, fetchPosts, deletePost } = useBoardPosts();
const toast = useToast();

const availableGhosts = [
  {
    value: "disbelieving",
    label: "Disbelieving",
    image: "/ghosties/Ghost-Disbelieving.png",
  },
  {
    value: "double-take",
    label: "Double Take",
    image: "/ghosties/Ghost-Double-Take.png",
  },
  {
    value: "exasperated",
    label: "Exasperated",
    image: "/ghosties/Ghost-Exasperated.png",
  },
  { value: "mild", label: "Mild", image: "/ghosties/Ghost-Mild.png" },
  { value: "sweet", label: "Sweet", image: "/ghosties/Ghost-Sweet.png" },
  { value: "wtf", label: "WTF", image: "/ghosties/Ghost-WTF.png" },
];

// Compute current UTC offset for an IANA timezone (DST-aware).
const utcOffset = (tz) => {
  try {
    const parts = new Intl.DateTimeFormat("en-US", {
      timeZone: tz,
      timeZoneName: "longOffset",
    }).formatToParts(new Date());
    const name = parts.find((p) => p.type === "timeZoneName")?.value || "";
    // "GMT-05:00" → "UTC-05:00"; "GMT" → "UTC+00:00"
    if (name === "GMT") return "UTC+00:00";
    return name.replace("GMT", "UTC");
  } catch {
    return "";
  }
};

// Include the saved timezone as a custom option if it's not in the curated list.
const timezoneItems = computed(() => {
  const saved = formData.timeZone;
  const list = TIMEZONE_OPTIONS.map((t) => {
    const off = utcOffset(t.value);
    return { ...t, label: off ? `${t.label} (${off})` : t.label };
  });
  if (saved && !TIMEZONE_OPTIONS.some((t) => t.value === saved)) {
    const off = utcOffset(saved);
    list.unshift({ label: off ? `${saved} (${off})` : saved, value: saved });
  }
  return list;
});

const notificationToggles = [
  {
    key: "events",
    label: "Registration & cancellation emails",
    sub: "Confirmation when you register for an event, and notice if it's cancelled",
  },
];

const { data: tagsData } = await useFetch("/api/tags");

const craftTags = computed(() =>
  (tagsData.value?.tags || []).filter((t) => t.pool === "craft"),
);

const showTagSuggestModal = ref(false);
const tagSuggestPool = ref("");

const openTagSuggest = (pool) => {
  tagSuggestPool.value = pool;
  showTagSuggestModal.value = true;
};

const formData = reactive({
  name: "",
  pronouns: "",
  timeZone: "",
  avatar: "",
  studio: "",
  bio: "",
  location: "",
  showInDirectory: true,
  craftTags: [],
  boardSlackHandle: "",
  notifications: {
    events: true,
  },
});

const loading = ref(false);
const saving = ref(false);
const initialData = ref(null);

const recentActivity = ref([]);
const activityLoading = ref(false);

const formatActivityTime = (date) => {
  const now = new Date();
  const d = new Date(date);
  const diff = Math.floor((now - d) / 1000);
  if (diff < 60) return "just now";
  if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
  if (diff < 604800) return `${Math.floor(diff / 86400)}d ago`;
  return d.toLocaleDateString("en-US", {
    month: "short",
    day: "numeric",
    year: d.getFullYear() !== now.getFullYear() ? "numeric" : undefined,
  });
};

const loadRecentActivity = async () => {
  activityLoading.value = true;
  try {
    const data = await $fetch("/api/members/me/activity", {
      params: { limit: 5 },
    });
    recentActivity.value = data.entries || [];
  } catch (err) {
    console.error("Failed to load activity:", err);
    recentActivity.value = [];
  } finally {
    activityLoading.value = false;
  }
};

const memberId = computed(() => memberData.value?._id || memberData.value?.id);

const hasChanges = computed(() => {
  return JSON.stringify(formData) !== JSON.stringify(initialData.value);
});

const loadProfile = () => {
  if (!memberData.value) return;

  formData.name = memberData.value.name || "";
  formData.pronouns = memberData.value.pronouns || "";
  formData.timeZone = memberData.value.timeZone || "";
  formData.avatar = memberData.value.avatar || "";
  formData.studio = memberData.value.studio || "";
  formData.bio = memberData.value.bio || "";
  formData.location = memberData.value.location || "";
  formData.showInDirectory = memberData.value.showInDirectory ?? true;

  formData.craftTags = Array.isArray(memberData.value.craftTags)
    ? [...memberData.value.craftTags]
    : [];

  const board = memberData.value.board || {};
  formData.boardSlackHandle = board.slackHandle || "";

  const notifs = memberData.value.notifications || {};
  formData.notifications.events = notifs.events ?? true;

  initialData.value = JSON.parse(JSON.stringify(formData));
};

const handleSubmit = async () => {
  saving.value = true;

  try {
    await $fetch("/api/members/profile", {
      method: "PATCH",
      body: { ...formData },
    });

    await checkMemberStatus();
    loadProfile();

    toast.add({ title: "Profile updated", color: "success" });
  } catch (error) {
    console.error("Profile save error:", error);
    toast.add({
      title: "Update failed",
      description:
        error.data?.statusMessage || error.data?.message || "Please try again.",
      color: "error",
    });
  } finally {
    saving.value = false;
  }
};

const resetForm = () => {
  loadProfile();
};

onMounted(async () => {
  if (!memberData.value) {
    loading.value = true;
    const isAuthenticated = await checkMemberStatus();
    loading.value = false;

    if (!isAuthenticated) {
      openLoginModal({
        title: "Sign in to your profile",
        description: "Enter your email to manage your profile settings",
      });
      return;
    }
  }

  loadProfile();

  if (memberId.value) {
    await Promise.allSettled([
      fetchPosts({ author: memberId.value }),
      loadRecentActivity(),
    ]);
  }
});

const postExcerpt = (post) => {
  const text = post.seeking || post.offering || "";
  if (text.length <= 80) return text;
  return text.slice(0, 80).trimEnd() + "...";
};

const handleDeletePost = async (post) => {
  if (!window.confirm(`Delete "${post.title}"?`)) return;
  try {
    await deletePost(post._id, { author: memberId.value });
  } catch (error) {
    console.error("Delete post error:", error);
    toast.add({
      title: "Failed to delete post",
      description: error.data?.message || "Please try again.",
      color: "error",
    });
  }
};

useHead({
  title: "Edit Profile - Ghost Guild",
});
</script>

<style scoped>
/* ---- LOADING / EMPTY STATE ---- */
.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 80px 20px;
  text-align: center;
}

/* ---- MULTI-COLUMN ROWS ---- */
.row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* ---- FIELD LABELS (distinct from .section-label) ---- */
.field label {
  font-size: 11px;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-dim);
}

/* ---- SOLID INPUT BORDERS ---- */
.field input,
.field select,
.field textarea {
  border-style: solid;
}

.field :deep(.tags) {
  border-style: solid;
}

/* ---- VIEW PROFILE LINK ---- */
.view-profile-link {
  display: inline-block;
  margin-top: 8px;
  font-size: 12px;
  color: var(--candle);
  text-decoration: none;
}
.view-profile-link:hover {
  text-decoration: underline;
}

/* ---- AVATAR PICKER ---- */
.avatar-row {
  display: flex;
  gap: 6px;
  align-items: center;
}

.avatar-option {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  cursor: pointer;
  padding: 3px;
  transition: all 0.12s;
}

.avatar-option img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.avatar-option:hover {
  border-color: var(--candle-dim);
  background: var(--surface-hover);
}

.avatar-option.selected {
  border: 2px solid var(--candle);
  background: var(--surface);
}

/* ---- TEXTAREA RESIZE ---- */
.field textarea {
  resize: vertical;
}

/* ---- CHAR COUNT ---- */
.char-count {
  font-size: 10px;
  color: var(--text-faint);
  text-align: right;
  margin-top: 2px;
}

/* ---- TOGGLE FIELD ---- */
.toggle-field {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
}

.toggle-label {
  font-size: 12px;
  color: var(--text);
  line-height: 1.4;
}

.toggle-sub {
  display: block;
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 1px;
}

/* ---- FIELD HELPER TEXT ---- */
.field-help {
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 4px;
}

/* ---- YOUR POSTS LIST ---- */
.posts-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 20px;
  margin-bottom: 8px;
}

.posts-heading {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}

.posts-new-link {
  font-size: 12px;
  color: var(--candle);
  text-decoration: none;
}

.posts-new-link:hover {
  text-decoration: underline;
}

.posts-empty {
  font-size: 12px;
  color: var(--text-faint);
  padding: 12px 0;
  border-top: 1px dashed var(--border);
}

.posts-empty-link {
  color: var(--candle);
  text-decoration: none;
}

.posts-empty-link:hover {
  text-decoration: underline;
}

.posts-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px dashed var(--border);
}

.post-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px dashed var(--border);
}

.post-body {
  flex: 1;
  min-width: 0;
}

.post-title {
  font-size: 13px;
  color: var(--text);
  margin-bottom: 2px;
}

.post-excerpt {
  font-size: 11px;
  color: var(--text-faint);
  line-height: 1.4;
}

.post-actions {
  display: flex;
  gap: 10px;
  flex-shrink: 0;
}

.post-action {
  font-size: 11px;
  color: var(--candle);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
}

.post-action:hover {
  text-decoration: underline;
}

.post-action-danger {
  color: var(--ember);
}

/* ---- RECENT ACTIVITY ---- */
.activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px dashed var(--border);
}
.activity-item {
  padding: 8px 0;
  border-bottom: 1px dashed var(--border);
  font-size: 12px;
  color: var(--text);
  line-height: 1.5;
}
.activity-time {
  font-size: 10px;
  color: var(--text-faint);
  margin-bottom: 2px;
}
.activity-text {
  color: var(--text);
}
.activity-link {
  color: var(--candle);
  text-decoration: none;
}
.activity-link:hover {
  text-decoration: underline;
}
.activity-empty {
  font-size: 12px;
  color: var(--text-faint);
  padding: 10px 0;
}

/* ---- DISABLED BUTTON ---- */
.btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ---- SAVE BAR ---- */
.save-bar {
  flex-shrink: 0;
  padding: 24px 28px;
  margin-top: 0;
  border-top: 1px dashed var(--border);
  display: flex;
  align-items: center;
  gap: 12px;
}

/* ---- RESPONSIVE ---- */
@media (max-width: 768px) {
  .row-2 {
    grid-template-columns: 1fr;
  }

  .save-bar {
    padding-left: 16px;
    padding-right: 16px;
    flex-wrap: wrap;
  }
}
</style>

