<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from "vue";
import { apiGet, apiPatch, apiPost } from "../api";
import { authState } from "../auth";
import FormStatus from "../components/FormStatus.vue";
import PageHeader from "../components/PageHeader.vue";
import { liveUpdateState } from "../realtime";
import type { OrganizationUser } from "../types";

const availableRoles = [
  { code: "owner", label: "Besitzer" },
  { code: "admin", label: "Admin" },
  { code: "sales", label: "Vertrieb" },
  { code: "accounting", label: "Buchhaltung" },
  { code: "viewer", label: "Lesen" }
];

const form = reactive({
  email: "",
  roles: ["viewer"]
});
const users = ref<OrganizationUser[]>([]);
const listMessage = ref("Noch keine Benutzer geladen.");
const status = ref("");
const statusKind = ref<"info" | "success" | "error">("info");
const roleDrafts = ref<Record<string, string[]>>({});
const savingUserId = ref<string | null>(null);
const currentUser = computed(() => users.value.find((user) => user.user_id === authState.session?.userId));
const canManageRoles = computed(() => currentUser.value?.roles.includes("owner") === true);

async function invite() {
  const result = await apiPost<{ dev_invitation_token?: string }>("/api/v1/organizations/current/invitations", form);
  status.value = result.ok
    ? `Einladung angelegt.${result.data.dev_invitation_token ? ` Dev-Token: ${result.data.dev_invitation_token}` : ""}`
    : result.message;
  statusKind.value = result.ok ? "success" : "error";
  if (result.ok) {
    form.email = "";
    form.roles = ["viewer"];
    await loadUsers();
  }
}

async function loadUsers() {
  const result = await apiGet<OrganizationUser[]>("/api/v1/organizations/current/users");
  if (!result.ok) {
    users.value = [];
    listMessage.value = result.message;
    return;
  }
  users.value = result.data;
  roleDrafts.value = Object.fromEntries(result.data.map((user) => [user.user_id, [...user.roles]]));
  listMessage.value = "Keine Benutzer vorhanden.";
}

async function saveRoles(user: OrganizationUser) {
  const roles = roleDrafts.value[user.user_id] ?? [];
  savingUserId.value = user.user_id;
  const result = await apiPatch(`/api/v1/organizations/current/users/${encodeURIComponent(user.user_id)}/roles`, { roles });
  savingUserId.value = null;
  status.value = result.ok ? "Benutzerrechte gespeichert." : result.message;
  statusKind.value = result.ok ? "success" : "error";
  if (result.ok) await loadUsers();
}

function roleLabel(code: string) {
  return availableRoles.find((role) => role.code === code)?.label ?? code;
}

onMounted(loadUsers);
watch(
  () => liveUpdateState.revision,
  () => {
    if (users.value.length > 0) loadUsers();
  }
);
</script>

<template>
  <PageHeader title="Benutzerrechte" description="Benutzer einladen und Rollen verwalten." />
  <section class="panel form-panel">
    <form @submit.prevent="invite">
      <label class="field">
        <span>E-Mail-Adresse</span>
        <input v-model="form.email" type="email" placeholder="kollege@example.com" required />
      </label>
      <label class="field">
        <span>Rollen</span>
        <select v-model="form.roles" multiple>
          <option v-for="role in availableRoles" :key="role.code" :value="role.code">{{ role.label }}</option>
        </select>
      </label>
      <div class="form-actions">
        <button type="submit" :disabled="!canManageRoles">Einladung senden</button>
        <button type="button" class="secondary" @click="loadUsers">Benutzer laden</button>
      </div>
      <p v-if="!canManageRoles" class="muted">Nur der Besitzer der Firma darf Rechte vergeben oder ändern.</p>
      <FormStatus :message="status" :kind="statusKind" />
    </form>
  </section>
  <section class="panel">
    <div class="section-title">
      <h2>Benutzerliste</h2>
    </div>
    <p v-if="users.length === 0" class="empty">{{ listMessage }}</p>
    <div v-else class="data-table users">
      <div class="table-head">E-Mail</div>
      <div class="table-head">Status</div>
      <div class="table-head">Rollen</div>
      <div class="table-head">Aktion</div>
      <template v-for="user in users" :key="user.user_id">
        <div>{{ user.email }}</div>
        <span class="status-pill">{{ user.status }}</span>
        <div v-if="canManageRoles" class="role-checks">
          <label v-for="role in availableRoles" :key="role.code" class="check-row compact">
            <input v-model="roleDrafts[user.user_id]" type="checkbox" :value="role.code" />
            <span>{{ role.label }}</span>
          </label>
        </div>
        <div v-else>{{ user.roles.map(roleLabel).join(", ") }}</div>
        <div>
          <button
            type="button"
            class="secondary"
            :disabled="!canManageRoles || savingUserId === user.user_id"
            @click="saveRoles(user)"
          >
            Speichern
          </button>
        </div>
      </template>
    </div>
  </section>
</template>
