<script setup lang="ts">
import { X } from "lucide-vue-next";
import { ref, onMounted } from 'vue'
import {
  searchUsers,
  listGroups,
  listProjectShares,
  createProjectShare,
  updateProjectShare,
  deleteProjectShare,
  listNoteShares,
  createNoteShare,
  updateNoteShare,
  deleteNoteShare,
  type ShareEntry,
  type GroupEntry,
  type UserSearchResult,
} from '@/api/client'

const props = defineProps<{
  resourceType: 'project' | 'note'
  resourceId: number
  resourceTitle: string
}>()
const emit = defineEmits<{ close: [] }>()

const addMode = ref<'user' | 'group'>('user')
const userQuery = ref('')
const userResults = ref<UserSearchResult[]>([])
const selectedUser = ref<UserSearchResult | null>(null)
const selectedGroupId = ref<number | ''>('')
const newPermission = ref('viewer')
const groups = ref<GroupEntry[]>([])
const shares = ref<ShareEntry[]>([])
const saving = ref(false)

let searchTimer: ReturnType<typeof setTimeout> | null = null

function debounceSearch() {
  if (searchTimer) clearTimeout(searchTimer)
  searchTimer = setTimeout(async () => {
    if (userQuery.value.length < 2) { userResults.value = []; return }
    userResults.value = await searchUsers(userQuery.value)
  }, 300)
}

function selectUser(u: UserSearchResult) {
  selectedUser.value = u
  userQuery.value = u.username
  userResults.value = []
}

async function loadShares() {
  if (props.resourceType === 'project') {
    shares.value = await listProjectShares(props.resourceId)
  } else {
    shares.value = await listNoteShares(props.resourceId)
  }
}

async function addShare() {
  if (saving.value) return
  saving.value = true
  try {
    const body: { user_id?: number; group_id?: number; permission: string } = {
      permission: newPermission.value,
    }
    if (addMode.value === 'user' && selectedUser.value) {
      body.user_id = selectedUser.value.id
    } else if (addMode.value === 'group' && selectedGroupId.value) {
      body.group_id = selectedGroupId.value as number
    } else {
      return
    }
    if (props.resourceType === 'project') {
      await createProjectShare(props.resourceId, body)
    } else {
      await createNoteShare(props.resourceId, body)
    }
    selectedUser.value = null
    userQuery.value = ''
    selectedGroupId.value = ''
    newPermission.value = 'viewer'
    await loadShares()
  } finally {
    saving.value = false
  }
}

async function changePermission(share: ShareEntry, permission: string) {
  if (props.resourceType === 'project') {
    await updateProjectShare(props.resourceId, share.id, permission)
  } else {
    await updateNoteShare(props.resourceId, share.id, permission)
  }
  await loadShares()
}

async function removeShare(share: ShareEntry) {
  if (props.resourceType === 'project') {
    await deleteProjectShare(props.resourceId, share.id)
  } else {
    await deleteNoteShare(props.resourceId, share.id)
  }
  await loadShares()
}

onMounted(async () => {
  groups.value = await listGroups()
  await loadShares()
})
</script>

<template>
  <Teleport to="body">
    <div class="share-overlay" @click.self="emit('close')">
      <div class="share-dialog" role="dialog" :aria-label="`Share ${resourceTitle}`">
        <header class="share-header">
          <h2 class="share-title">Share "{{ resourceTitle }}"</h2>
          <button class="btn-close" @click="emit('close')" aria-label="Close"><X :size="16" /></button>
        </header>

        <!-- Add share form -->
        <div class="share-add">
          <div class="share-tabs">
            <button :class="['share-tab', { active: addMode === 'user' }]" @click="addMode = 'user'">User</button>
            <button :class="['share-tab', { active: addMode === 'group' }]" @click="addMode = 'group'">Group</button>
          </div>

          <div v-if="addMode === 'user'" class="share-target-form">
            <div class="user-search-wrap">
              <input
                v-model="userQuery"
                class="share-input"
                placeholder="Search by username or email…"
                @input="debounceSearch"
                autocomplete="off"
              />
              <ul v-if="userResults.length" class="user-results">
                <li v-for="u in userResults" :key="u.id" @click="selectUser(u)" class="user-result-item">
                  <span class="user-result-name">{{ u.username }}</span>
                </li>
              </ul>
            </div>
            <template v-if="selectedUser">
              <select v-model="newPermission" class="perm-select">
                <option value="viewer">Viewer</option>
                <option value="editor">Editor</option>
                <option value="admin">Admin</option>
              </select>
              <button class="btn-add-share" @click="addShare" :disabled="saving">Add</button>
            </template>
          </div>

          <div v-else class="share-target-form">
            <select v-model="selectedGroupId" class="share-input">
              <option value="" disabled>Select a group…</option>
              <option v-for="g in groups" :key="g.id" :value="g.id">{{ g.name }} ({{ g.member_count }} members)</option>
            </select>
            <select v-model="newPermission" class="perm-select">
              <option value="viewer">Viewer</option>
              <option value="editor">Editor</option>
              <option value="admin">Admin</option>
            </select>
            <button class="btn-add-share" @click="addShare" :disabled="saving || !selectedGroupId">Add</button>
          </div>
        </div>

        <!-- Current shares -->
        <div class="shares-list-wrap">
          <p class="shares-label">Current access</p>
          <ul class="shares-list">
            <li v-for="share in shares" :key="share.id" class="share-row">
              <span class="share-target-icon">{{ share.shared_with_user_id ? '👤' : '👥' }}</span>
              <span class="share-target-name">
                {{ share.shared_with_user_id ? share.username : share.group_name }}
              </span>
              <select
                class="perm-select-inline"
                :value="share.permission"
                @change="changePermission(share, ($event.target as HTMLSelectElement).value)"
              >
                <option value="viewer">Viewer</option>
                <option value="editor">Editor</option>
                <option value="admin">Admin</option>
              </select>
              <button class="btn-remove-share" @click="removeShare(share)" aria-label="Remove"><X :size="16" /></button>
            </li>
            <li v-if="!shares.length" class="shares-empty">Not shared with anyone yet</li>
          </ul>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<style scoped>
.share-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.share-dialog {
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  width: 480px;
  max-width: 95vw;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}

.share-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--color-border);
}

.share-title {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.1rem;
  font-weight: 700;
  margin: 0;
  color: var(--color-text);
}

.btn-close {
  background: none;
  border: none;
  color: var(--color-text-muted);
  cursor: pointer;
  font-size: 1.1rem;
  padding: 0.25rem;
  line-height: 1;
  border-radius: 4px;
  transition: color 0.15s;
}
.btn-close:hover { color: var(--color-text); }

.share-add {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid var(--color-border);
}

.share-tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 0.75rem;
}

.share-tab {
  background: none;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: 0.3rem 0.8rem;
  font-size: 0.82rem;
  cursor: pointer;
  color: var(--color-text-muted);
  transition: all 0.15s;
}
.share-tab.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.share-target-form {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  flex-wrap: wrap;
}

.user-search-wrap {
  flex: 1;
  position: relative;
}

.share-input {
  width: 100%;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: var(--color-bg-card);
  color: var(--color-text);
  font-size: 0.9rem;
  outline: none;
  transition: border-color 0.15s;
}
.share-input:focus { border-color: var(--color-primary); }

.user-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--color-bg-card);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  margin-top: 2px;
  list-style: none;
  padding: 0.25rem 0;
  z-index: 10;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
  max-height: 180px;
  overflow-y: auto;
}

.user-result-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.8rem;
  cursor: pointer;
  transition: background 0.1s;
}
.user-result-item:hover { background: var(--color-bg-secondary); }

.user-result-name { font-weight: 600; font-size: 0.88rem; }
.user-result-email { color: var(--color-text-muted); font-size: 0.8rem; }

.perm-select {
  padding: 0.45rem 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: var(--color-bg-card);
  color: var(--color-text);
  font-size: 0.85rem;
  cursor: pointer;
}

.btn-add-share {
  padding: 0.45rem 1rem;
  background: var(--gradient-cta);
  color: #fff;
  border: none;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s;
  white-space: nowrap;
}
.btn-add-share:disabled { opacity: 0.5; cursor: not-allowed; }

.shares-list-wrap {
  padding: 1rem 1.5rem 1.5rem;
}

.shares-label {
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
  margin: 0 0 0.5rem;
}

.shares-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.share-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  background: var(--color-bg-secondary);
}

.share-target-icon { font-size: 1rem; flex-shrink: 0; }
.share-target-name { flex: 1; font-size: 0.88rem; font-weight: 500; }

.perm-select-inline {
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-bg-card);
  color: var(--color-text);
  font-size: 0.8rem;
  cursor: pointer;
}

.btn-remove-share {
  background: none;
  border: none;
  color: var(--color-text-muted);
  cursor: pointer;
  font-size: 0.9rem;
  padding: 0.15rem 0.3rem;
  border-radius: 4px;
  transition: color 0.15s;
  flex-shrink: 0;
}
.btn-remove-share:hover { color: var(--color-danger, #ef4444); }

.shares-empty {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  text-align: center;
  padding: 0.75rem;
}
</style>
