<template>
  <div class="page-header">
    <h1>User Management</h1>
    <button class="btn-primary" @click="showCreateModal = true">Add User</button>
  </div>

  <div class="card">
    <div class="table-container">
      <table>
        <thead>
          <tr>
            <th>Username</th>
            <th>Email</th>
            <th>Name</th>
            <th>Roles</th>
            <th>Status</th>
            <th>Last Login</th>
            <th class="actions">Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr v-if="loading">
            <td colspan="7" class="loading">Loading...</td>
          </tr>
          <tr v-else-if="!users.length">
            <td colspan="7" class="empty">No users found</td>
          </tr>
          <tr v-for="user in users" :key="user.userid">
            <td>{{ user.username }}</td>
            <td>{{ user.email }}</td>
            <td>{{ [user.firstname, user.lastname].filter(Boolean).join(' ') || '-' }}</td>
            <td>
              <span
                v-for="role in user.roles"
                :key="role.roleid"
                class="badge"
                :class="roleBadgeClass(role)"
                :style="roleBadgeStyle(role)"
              >
                {{ role.rolename }}
              </span>
              <span v-if="!user.roles.length" class="text-muted">None</span>
            </td>
            <td>
              <span v-if="user.islocked" class="badge badge-danger">Locked</span>
              <span v-else-if="!user.isactive" class="badge badge-warning">Inactive</span>
              <span v-else class="badge badge-success">Active</span>
            </td>
            <td>{{ formatDate(user.lastlogindate) }}</td>
            <td class="actions">
              <button class="btn-sm" @click="editUser(user)">Edit</button>
              <button
                class="btn-sm btn-danger"
                @click="confirmDelete(user)"
                :disabled="user.userid === currentUserId"
              >
                Delete
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <!-- Roles Section -->
  <div class="page-header" style="margin-top: 2rem">
    <h2>Roles</h2>
    <button class="btn-secondary" @click="showRoleModal = true">Add Role</button>
  </div>

  <div class="card">
    <div class="table-container">
      <table>
        <thead>
          <tr>
            <th>Role Name</th>
            <th>Description</th>
            <th>Permissions</th>
            <th>Users</th>
            <th class="actions">Actions</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="role in roles" :key="role.roleid">
            <td>
              <span class="badge" :class="roleBadgeClass(role)" :style="roleBadgeStyle(role)">
                {{ role.rolename }}
              </span>
            </td>
            <td class="cell-truncate" :title="role.description">{{ role.description || '-' }}</td>
            <td>
              <span v-if="role.isadmin" class="text-muted">All permissions</span>
              <span v-else-if="role.permissions?.length">{{ role.permissions.length }} permissions</span>
              <span v-else class="text-muted">None</span>
            </td>
            <td>{{ role.usercount }}</td>
            <td class="actions">
              <button class="btn-sm" @click="editRole(role)">Edit</button>
              <button
                class="btn-sm btn-danger"
                @click="confirmDeleteRole(role)"
                :disabled="role.rolename === 'admin' || role.usercount > 0"
              >
                Delete
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

  <!-- User Modal -->
  <div v-if="showCreateModal || editingUser" class="modal-overlay">
    <div class="modal">
      <div class="modal-header">
        <h3>{{ editingUser ? 'Edit User' : 'Create User' }}</h3>
        <button class="close-btn" @click="closeUserModal">&times;</button>
      </div>
      <div class="modal-body">
        <form @submit.prevent="saveUser">
          <div class="form-group">
            <label>Username</label>
            <input
              type="text"
              v-model="userForm.username"
              required
              :disabled="!!editingUser"
              placeholder="username"
            >
          </div>
          <div class="form-group">
            <label>Email</label>
            <input type="email" v-model="userForm.email" required placeholder="user@example.com">
          </div>
          <div class="form-row">
            <div class="form-group">
              <label>First Name</label>
              <input type="text" v-model="userForm.firstname" placeholder="John">
            </div>
            <div class="form-group">
              <label>Last Name</label>
              <input type="text" v-model="userForm.lastname" placeholder="Doe">
            </div>
          </div>
          <div class="form-group">
            <label>{{ editingUser ? 'New Password (leave blank to keep current)' : 'Password' }}</label>
            <input
              type="password"
              v-model="userForm.password"
              :required="!editingUser"
              placeholder="********"
            >
          </div>
          <div class="form-group">
            <label>Roles</label>
            <div class="checkbox-group">
              <label v-for="role in roles" :key="role.roleid" class="checkbox-label">
                <input
                  type="checkbox"
                  :value="role.roleid"
                  v-model="userForm.roles"
                >
                {{ role.rolename }}
              </label>
            </div>
          </div>
          <div class="form-group" v-if="editingUser">
            <label class="checkbox-label">
              <input type="checkbox" v-model="userForm.isactive">
              Account Active
            </label>
          </div>
          <div class="form-group" v-if="editingUser && editingUser.islocked">
            <label class="checkbox-label">
              <input type="checkbox" v-model="userForm.unlock">
              Unlock Account
            </label>
          </div>
          <div class="form-actions">
            <button type="button" class="btn-secondary" @click="closeUserModal">Cancel</button>
            <button type="submit" class="btn-primary" :disabled="saving">
              {{ saving ? 'Saving...' : (editingUser ? 'Update' : 'Create') }}
            </button>
          </div>
        </form>
      </div>
    </div>
  </div>

  <!-- Role Modal -->
  <div v-if="showRoleModal || editingRole" class="modal-overlay">
    <div class="modal modal-lg">
      <div class="modal-header">
        <h3>{{ editingRole ? 'Edit Role' : 'Create Role' }}</h3>
        <button class="close-btn" @click="closeRoleModal">&times;</button>
      </div>
      <div class="modal-body">
        <form @submit.prevent="saveRole">
          <div class="form-row">
            <div class="form-group">
              <label>Role Name</label>
              <input
                type="text"
                v-model="roleForm.rolename"
                required
                :disabled="!!editingRole"
                placeholder="rolename"
              >
            </div>
            <div class="form-group">
              <label>Description</label>
              <input type="text" v-model="roleForm.description" placeholder="Role description">
            </div>
          </div>

          <div class="form-group">
            <label>Badge color</label>
            <ColorSwatchPicker v-model="roleForm.color" />
          </div>

          <div class="form-group" v-if="!editingRole?.isadmin">
            <label>Permissions</label>
            <p class="text-muted" style="font-size: 0.85rem; margin: 0 0 0.5rem 0">
              Select which actions this role can perform
            </p>
            <div class="permissions-grid">
              <div v-for="(perms, category) in permissionsGrouped" :key="category" class="permission-category">
                <div class="category-header">
                  <label class="checkbox-label">
                    <input
                      type="checkbox"
                      :checked="isCategoryFullySelected(category)"
                      :indeterminate="isCategoryPartiallySelected(category)"
                      @change="toggleCategory(category, $event.target.checked)"
                    >
                    <strong>{{ formatCategory(category) }}</strong>
                  </label>
                </div>
                <div class="category-perms">
                  <label v-for="p in perms" :key="p.name" class="checkbox-label perm-item">
                    <input
                      type="checkbox"
                      :value="p.name"
                      v-model="roleForm.permissions"
                    >
                    {{ p.description }}
                  </label>
                </div>
              </div>
            </div>
          </div>
          <div v-else class="form-group">
            <label>Permissions</label>
            <p class="text-muted">Admin role has all permissions by default</p>
          </div>

          <div class="form-actions">
            <button type="button" class="btn-secondary" @click="closeRoleModal">Cancel</button>
            <button type="submit" class="btn-primary" :disabled="saving">
              {{ saving ? 'Saving...' : (editingRole ? 'Update' : 'Create') }}
            </button>
          </div>
        </form>
      </div>
    </div>
  </div>

  <!-- Delete Confirmation -->
  <div v-if="deletingUser" class="modal-overlay" @click.self="deletingUser = null">
    <div class="modal modal-sm">
      <div class="modal-header">
        <h3>Delete User</h3>
        <button class="close-btn" @click="deletingUser = null">&times;</button>
      </div>
      <div class="modal-body">
        <p>Are you sure you want to delete user <strong>{{ deletingUser.username }}</strong>?</p>
        <p class="text-muted">This action cannot be undone.</p>
        <div class="form-actions">
          <button class="btn-secondary" @click="deletingUser = null">Cancel</button>
          <button class="btn-danger" @click="deleteUser" :disabled="saving">
            {{ saving ? 'Deleting...' : 'Delete' }}
          </button>
        </div>
      </div>
    </div>
  </div>

  <div v-if="error" class="error-toast">{{ error }}</div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { usersApi } from '../../api'
import { useAuthStore } from '../../stores/auth'
import { apiError } from '../../utils/apiError'
import ColorSwatchPicker from '@/components/ColorSwatchPicker.vue'

const DEFAULT_ROLE_COLOR = '#0d6efd'

const authStore = useAuthStore()
const currentUserId = authStore.user?.userid

const users = ref([])
const roles = ref([])
const permissions = ref([])
const permissionsGrouped = ref({})
const loading = ref(true)
const saving = ref(false)
const error = ref('')

// Modals
const showCreateModal = ref(false)
const showRoleModal = ref(false)
const editingUser = ref(null)
const editingRole = ref(null)
const deletingUser = ref(null)

// Forms
const userForm = reactive({
  username: '',
  email: '',
  firstname: '',
  lastname: '',
  password: '',
  roles: [],
  isactive: true,
  unlock: false
})

const roleForm = reactive({
  rolename: '',
  description: '',
  color: DEFAULT_ROLE_COLOR,
  permissions: []
})

// Role badge: use the role's own color when set (contrast-aware text), else
// fall back to the legacy admin=primary / other=gray classes.
function isLightColor(color) {
  if (!color) return false
  const hex = color.replace('#', '')
  if (hex.length !== 6) return false
  const r = parseInt(hex.slice(0, 2), 16)
  const g = parseInt(hex.slice(2, 4), 16)
  const b = parseInt(hex.slice(4, 6), 16)
  return (r * 299 + g * 587 + b * 114) / 1000 > 155
}

function roleBadgeClass(role) {
  if (role.color) return ''
  return role.rolename === 'admin' ? 'badge-primary' : 'badge-secondary'
}

function roleBadgeStyle(role) {
  if (!role.color) return null
  return { background: role.color, color: isLightColor(role.color) ? '#000' : '#fff' }
}

async function loadData() {
  loading.value = true
  try {
    const [usersRes, rolesRes, permsRes] = await Promise.all([
      usersApi.list(),
      usersApi.roles.list(),
      usersApi.permissions.list()
    ])
    users.value = usersRes.data.data
    roles.value = rolesRes.data.data
    permissions.value = permsRes.data.data.permissions
    permissionsGrouped.value = permsRes.data.data.grouped
  } catch (e) {
    error.value = 'Failed to load users'
    setTimeout(() => error.value = '', 3000)
  } finally {
    loading.value = false
  }
}

function formatCategory(cat) {
  return cat.charAt(0).toUpperCase() + cat.slice(1)
}

function isCategoryFullySelected(category) {
  const catPerms = permissionsGrouped.value[category] || []
  return catPerms.length > 0 && catPerms.every(p => roleForm.permissions.includes(p.name))
}

function isCategoryPartiallySelected(category) {
  const catPerms = permissionsGrouped.value[category] || []
  const selected = catPerms.filter(p => roleForm.permissions.includes(p.name))
  return selected.length > 0 && selected.length < catPerms.length
}

function toggleCategory(category, checked) {
  const catPerms = permissionsGrouped.value[category] || []
  const permNames = catPerms.map(p => p.name)

  if (checked) {
    // Add all perms from this category
    for (const name of permNames) {
      if (!roleForm.permissions.includes(name)) {
        roleForm.permissions.push(name)
      }
    }
  } else {
    // Remove all perms from this category
    roleForm.permissions = roleForm.permissions.filter(p => !permNames.includes(p))
  }
}

function formatDate(iso) {
  if (!iso) return 'Never'
  return new Date(iso).toLocaleDateString()
}

function editUser(user) {
  editingUser.value = user
  userForm.username = user.username
  userForm.email = user.email
  userForm.firstname = user.firstname || ''
  userForm.lastname = user.lastname || ''
  userForm.password = ''
  userForm.roles = user.roles.map(r => r.roleid)
  userForm.isactive = user.isactive
  userForm.unlock = false
}

function closeUserModal() {
  showCreateModal.value = false
  editingUser.value = null
  Object.assign(userForm, {
    username: '', email: '', firstname: '', lastname: '',
    password: '', roles: [], isactive: true, unlock: false
  })
}

async function saveUser() {
  saving.value = true
  error.value = ''
  try {
    const data = {
      email: userForm.email,
      firstname: userForm.firstname || null,
      lastname: userForm.lastname || null,
      roles: userForm.roles
    }

    if (editingUser.value) {
      data.isactive = userForm.isactive
      if (userForm.password) data.password = userForm.password
      if (userForm.unlock) data.unlock = true
      await usersApi.update(editingUser.value.userid, data)
    } else {
      data.username = userForm.username
      data.password = userForm.password
      await usersApi.create(data)
    }

    closeUserModal()
    await loadData()
  } catch (e) {
    error.value = apiError(e, 'Failed to save user')
    setTimeout(() => error.value = '', 3000)
  } finally {
    saving.value = false
  }
}

function confirmDelete(user) {
  deletingUser.value = user
}

async function deleteUser() {
  saving.value = true
  try {
    await usersApi.delete(deletingUser.value.userid)
    deletingUser.value = null
    await loadData()
  } catch (e) {
    error.value = apiError(e, 'Failed to delete user')
    setTimeout(() => error.value = '', 3000)
  } finally {
    saving.value = false
  }
}

// Roles
function editRole(role) {
  editingRole.value = role
  roleForm.rolename = role.rolename
  roleForm.description = role.description || ''
  roleForm.color = role.color || DEFAULT_ROLE_COLOR
  roleForm.permissions = role.permissions ? [...role.permissions] : []
}

function closeRoleModal() {
  showRoleModal.value = false
  editingRole.value = null
  roleForm.rolename = ''
  roleForm.description = ''
  roleForm.color = DEFAULT_ROLE_COLOR
  roleForm.permissions = []
}

async function saveRole() {
  saving.value = true
  error.value = ''
  try {
    const data = {
      description: roleForm.description,
      color: roleForm.color,
      permissions: roleForm.permissions
    }

    if (editingRole.value) {
      await usersApi.roles.update(editingRole.value.roleid, data)
    } else {
      data.rolename = roleForm.rolename
      await usersApi.roles.create(data)
    }
    closeRoleModal()
    await loadData()
  } catch (e) {
    error.value = apiError(e, 'Failed to save role')
    setTimeout(() => error.value = '', 3000)
  } finally {
    saving.value = false
  }
}

function confirmDeleteRole(role) {
  if (confirm(`Delete role "${role.rolename}"?`)) {
    deleteRole(role)
  }
}

async function deleteRole(role) {
  try {
    await usersApi.roles.delete(role.roleid)
    await loadData()
  } catch (e) {
    error.value = apiError(e, 'Failed to delete role')
    setTimeout(() => error.value = '', 3000)
  }
}

onMounted(loadData)
</script>

<style scoped>
.badge {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-size: 0.8rem;
  margin-right: 0.25rem;
}

.badge-primary { background: var(--primary); color: white; }
.badge-secondary { background: var(--secondary); color: white; }
.badge-success { background: var(--success); color: white; }
.badge-warning { background: var(--warning); color: #000; }
.badge-danger { background: var(--danger); color: white; }

.text-muted { color: var(--text-light); }

.btn-primary {
  background: var(--primary);
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
}

.btn-primary:hover { background: var(--primary-dark); }

.btn-secondary {
  background: var(--secondary);
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
}

.btn-danger {
  background: var(--danger);
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
}

.btn-sm {
  padding: 0.25rem 0.5rem;
  font-size: 0.85rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  color: var(--text);
}

.btn-sm:hover { background: var(--border); }
.btn-sm.btn-danger { background: var(--danger); color: white; border-color: var(--danger); }
.btn-sm:disabled { opacity: 0.5; cursor: not-allowed; }

.actions {
  white-space: nowrap;
}

.actions button { margin-right: 0.25rem; }

.loading, .empty {
  text-align: center;
  color: var(--text-light);
  padding: 2rem;
}

/* Modal */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal {
  /* SOLID, not var(--bg-card): the card variable is translucent in dark mode,
     which left this dialog see-through over its own overlay. */
  background: var(--bg-card-solid);
  border: 1px solid var(--border);
  border-radius: 8px;
  width: 500px;
  max-width: 90vw;
  max-height: 90vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.modal-sm { width: 400px; }
.modal-lg { width: 700px; }

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

.modal-header h3 { margin: 0; }

.close-btn {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--text-light);
  line-height: 1;
}

.modal-body {
  padding: 1rem;
  overflow-y: auto;
}

.form-group {
  margin-bottom: 1rem;
}

.form-group label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.9rem;
  color: var(--text);
}

.form-group input,
.form-group textarea {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--text);
}

.form-group input:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--primary);
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
}

.checkbox-label input[type="checkbox"] {
  width: auto;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1rem;
}

.error-toast {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  background: var(--danger);
  color: white;
  padding: 0.75rem 1rem;
  border-radius: 4px;
  z-index: 1001;
}

/* Permissions grid */
.permissions-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  max-height: 300px;
  overflow-y: auto;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
}

.permission-category {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.5rem;
}

.category-header {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
  margin-bottom: 0.5rem;
}

.category-perms {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.perm-item {
  font-size: 0.85rem;
  padding: 0.25rem 0;
}
</style>
