<script setup lang="ts">
// Tier 2 Block C — multi-host team management. Shown as a card on the event
// detail page; visible to anyone with viewer+ role. Action buttons (invite,
// role change, remove) are gated to owners — the server enforces this too.

interface Collaborator {
  user_id: string
  name: string
  email: string
  role: 'owner' | 'editor' | 'viewer'
  invited_at: string
  accepted_at?: string | null
}

interface PendingInvite {
  email: string
  role: 'owner' | 'editor' | 'viewer'
  expires_at: string
  created_at: string
}

interface TeamResponse {
  collaborators: Collaborator[]
  pending: PendingInvite[]
  your_role: 'owner' | 'editor' | 'viewer'
}

const props = defineProps<{
  eventId: string
  yourRole?: 'owner' | 'editor' | 'viewer' | null
}>()

const collaborators = ref<Collaborator[]>([])
const pending = ref<PendingInvite[]>([])
const loading = ref(true)
const error = ref<string | null>(null)

const isOwner = computed(() => props.yourRole === 'owner')

async function refresh() {
  try {
    const data = await useApi<TeamResponse>(`/events/${props.eventId}/collaborators`)
    collaborators.value = data.collaborators || []
    pending.value = data.pending || []
  } catch (e: any) {
    error.value = useErrMessage(e, 'Could not load team')
  } finally {
    loading.value = false
  }
}
onMounted(refresh)

// --- invite modal ---
const inviting = ref(false)
const inviteEmail = ref('')
const inviteRole = ref<'editor' | 'viewer'>('editor')
const inviteInFlight = ref(false)
const inviteError = ref<string | null>(null)

function openInvite() {
  inviteEmail.value = ''
  inviteRole.value = 'editor'
  inviteError.value = null
  inviting.value = true
}

async function sendInvite() {
  inviteInFlight.value = true
  inviteError.value = null
  try {
    await useApi(`/events/${props.eventId}/collaborators`, {
      method: 'POST',
      body: { email: inviteEmail.value.trim(), role: inviteRole.value },
    })
    inviting.value = false
    await refresh()
  } catch (e: any) {
    inviteError.value = useErrMessage(e, 'Could not send invite')
  } finally {
    inviteInFlight.value = false
  }
}

// --- role change ---
async function changeRole(c: Collaborator, role: 'owner' | 'editor' | 'viewer') {
  if (c.role === role) return
  try {
    await useApi(`/events/${props.eventId}/collaborators/${c.user_id}`, {
      method: 'PATCH',
      body: { role },
    })
    await refresh()
  } catch (e: any) {
    error.value = useErrMessage(e, 'Could not change role')
  }
}

// --- remove ---
async function removeCollaborator(c: Collaborator) {
  if (!confirm(`Remove ${c.name || c.email} from this event?`)) return
  try {
    await useApi(`/events/${props.eventId}/collaborators/${c.user_id}`, { method: 'DELETE' })
    await refresh()
  } catch (e: any) {
    error.value = useErrMessage(e, 'Could not remove collaborator')
  }
}

async function cancelPending(p: PendingInvite) {
  if (!confirm(`Cancel invitation to ${p.email}?`)) return
  try {
    await useApi(`/events/${props.eventId}/collaborators/pending?email=${encodeURIComponent(p.email)}`, {
      method: 'DELETE',
    })
    await refresh()
  } catch (e: any) {
    error.value = useErrMessage(e, 'Could not cancel invitation')
  }
}

function fmtDate(iso?: string | null) {
  if (!iso) return ''
  try { return new Date(iso).toLocaleDateString() } catch { return iso }
}
</script>

<template>
  <section class="card">
    <header class="mb-3 flex items-center justify-between">
      <h2 class="text-lg font-semibold">Team</h2>
      <button
        v-if="isOwner"
        type="button"
        class="btn-primary text-sm"
        @click="openInvite"
      >Invite</button>
    </header>
    <p class="mb-4 text-xs text-zinc-500">
      Collaborators can help manage this event. Owners can invite + change roles;
      editors can manage guests + send messages; viewers can read but not change.
    </p>

    <p v-if="error" class="mb-3 text-sm text-red-400">{{ error }}</p>

    <div v-if="loading" class="text-sm text-zinc-500">Loading team…</div>

    <ul v-else-if="collaborators.length" class="space-y-2">
      <li
        v-for="c in collaborators"
        :key="c.user_id"
        class="flex items-center justify-between rounded-md border border-zinc-800 bg-zinc-950 px-3 py-2"
      >
        <div class="min-w-0 flex-1">
          <div class="truncate text-sm font-medium text-zinc-100">{{ c.name || c.email }}</div>
          <div class="truncate text-xs text-zinc-500">{{ c.email }}</div>
        </div>
        <div class="flex items-center gap-2">
          <select
            v-if="isOwner"
            :value="c.role"
            class="rounded border border-zinc-700 bg-zinc-900 px-2 py-1 text-xs text-zinc-100"
            :aria-label="`Change role for ${c.name || c.email}`"
            @change="(e) => changeRole(c, ((e.target as HTMLSelectElement).value as any))"
          >
            <option value="owner">Owner</option>
            <option value="editor">Editor</option>
            <option value="viewer">Viewer</option>
          </select>
          <span v-else class="badge bg-zinc-800 capitalize text-zinc-300">{{ c.role }}</span>
          <button
            v-if="isOwner"
            type="button"
            class="rounded-md p-1 text-zinc-500 transition hover:bg-red-500/10 hover:text-red-300"
            :title="`Remove ${c.name || c.email}`"
            :aria-label="`Remove ${c.name || c.email}`"
            @click="removeCollaborator(c)"
          >
            <svg class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
              <path d="M6 6L14 14M14 6L6 14" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
            </svg>
          </button>
        </div>
      </li>
    </ul>

    <p v-else class="text-sm text-zinc-500">No collaborators yet.</p>

    <div v-if="pending.length" class="mt-4">
      <p class="mb-2 text-xs font-medium uppercase tracking-wider text-zinc-500">Pending invitations</p>
      <ul class="space-y-2">
        <li
          v-for="p in pending"
          :key="p.email"
          class="flex items-center justify-between rounded-md border border-amber-900/40 bg-amber-950/10 px-3 py-2"
        >
          <div class="min-w-0 flex-1">
            <div class="truncate text-sm font-medium text-zinc-100">{{ p.email }}</div>
            <div class="text-xs text-zinc-500">
              <span class="capitalize">{{ p.role }}</span> · expires {{ fmtDate(p.expires_at) }}
            </div>
          </div>
          <button
            v-if="isOwner"
            type="button"
            class="text-xs text-zinc-400 hover:text-red-300"
            @click="cancelPending(p)"
          >Cancel</button>
        </li>
      </ul>
    </div>

    <!-- Invite modal -->
    <Teleport to="body">
      <div
        v-if="inviting"
        class="fixed inset-0 z-40 flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm"
        @click.self="inviting = false"
      >
        <div
          role="dialog"
          aria-modal="true"
          aria-labelledby="invite-title"
          class="w-full max-w-md rounded-lg border border-zinc-800 bg-zinc-900 p-5 shadow-2xl"
        >
          <h3 id="invite-title" class="mb-1 text-base font-semibold">Invite a collaborator</h3>
          <p class="mb-4 text-xs text-zinc-500">
            They'll get an email with a link that's valid for 7 days. If they don't have a
            GuestGuard account yet, they'll be prompted to create one.
          </p>
          <form class="space-y-3" @submit.prevent="sendInvite">
            <div>
              <label class="label">Email</label>
              <input
                v-model="inviteEmail"
                type="email"
                required
                class="input"
                placeholder="teammate@example.com"
              />
            </div>
            <div>
              <label class="label">Role</label>
              <select v-model="inviteRole" class="input">
                <option value="editor">Editor — manage guests + send messages</option>
                <option value="viewer">Viewer — read-only access</option>
              </select>
            </div>
            <p v-if="inviteError" class="text-sm text-red-400">{{ inviteError }}</p>
            <div class="flex items-center justify-end gap-2 pt-2">
              <button
                type="button"
                class="text-sm text-zinc-400 hover:text-zinc-200"
                :disabled="inviteInFlight"
                @click="inviting = false"
              >Cancel</button>
              <button
                type="submit"
                class="btn-primary"
                :disabled="inviteInFlight || !inviteEmail.trim()"
              >{{ inviteInFlight ? 'Sending…' : 'Send invite' }}</button>
            </div>
          </form>
        </div>
      </div>
    </Teleport>
  </section>
</template>
