<script setup>
// Lists the AD_Users of a merchant (resolved from the bpartner) and lets an admin send each
// selected user their login details by e-mail. Recipient address per user is editable.
const props = defineProps({
  modelValue: { type: Boolean, default: false },
  bpartnerId: { type: [String, Number], default: '' },
  bpartnerName: { type: String, default: '' },
  isGerman: { type: Boolean, default: false }
})
const emit = defineEmits(['update:modelValue'])

const LOGIN_URL = 'https://app.logship.de'
const t = (de, en) => (props.isGerman ? de : en)

const loading = ref(false)
const users = ref([])      // { id, username, name, description, value, email, password, hasPassword, _selected, _email, _result }
const sending = ref(false)
const error = ref('')
const showPasswords = ref(false)
const resetPasswords = ref(false) // generate + save + send a fresh password for each selected user

const load = async () => {
  loading.value = true
  error.value = ''
  resetPasswords.value = false
  users.value = []
  try {
    const res = await $fetch('/api/admin/merchant-onboarding/bpartner-users', {
      headers: useRequestHeaders(['cookie']),
      params: { bpartnerId: props.bpartnerId }
    })
    users.value = (res?.users || []).map((u) => ({
      ...u,
      _selected: !!u.hasPassword && !!u.email, // preselect login users that have an e-mail
      _email: u.email || '',
      _result: null
    }))
  } catch (e) {
    error.value = e?.data?.message || e?.message || 'Failed to load users'
  } finally {
    loading.value = false
  }
}

watch(() => props.modelValue, (v) => { if (v && props.bpartnerId) load() })

const allSelected = computed({
  get: () => users.value.length > 0 && users.value.every((u) => u._selected),
  set: (v) => { users.value.forEach((u) => { u._selected = v }) }
})
const selectedCount = computed(() => users.value.filter((u) => u._selected).length)
const canSend = computed(() => !sending.value && users.value.some((u) => u._selected && u._email))

const close = () => { if (!sending.value) emit('update:modelValue', false) }

const send = async () => {
  sending.value = true
  for (const u of users.value) {
    if (!u._selected) continue
    u._result = { status: 'sending' }
    if (!u._email) { u._result = { status: 'error', msg: t('E-Mail fehlt', 'E-mail missing') }; continue }
    try {
      const res = await $fetch('/api/admin/merchant-onboarding/send-credentials', {
        method: 'POST',
        headers: useRequestHeaders(['cookie']),
        body: {
          toEmail: u._email,
          username: u.username,
          password: u.password || '',
          name: u.name || u.username || '',
          description: u.description || '',
          userId: u.id,
          bpartnerId: props.bpartnerId,
          resetPassword: resetPasswords.value,
        }
      })
      if (Number(res?.status) === 200) {
        if (resetPasswords.value && res?.newPassword) {
          u.password = res.newPassword
          u.hasPassword = true
        }
        // When the credentials send also just linked the user to their org's merchant role
        // (AD_User_Roles), note it so staff know the account is now login-ready. If the role
        // could NOT be ensured, warn — the mail went out but the user still can't sign in.
        const ra = res?.roleAssignment
        let roleNote = ''
        if (ra && (ra.status === 'assigned' || ra.status === 'reactivated')) {
          roleNote = t(' · Rolle zugewiesen', ' · role assigned')
        } else if (ra && (ra.status === 'skipped' || ra.status === 'error')) {
          roleNote = t(' · ⚠ keine Rolle', ' · ⚠ no role')
        }
        u._result = { status: 'ok', msg: (resetPasswords.value ? t('Gesendet · neues Passwort', 'Sent · new password') : t('Gesendet', 'Sent')) + roleNote }
      } else {
        u._result = { status: 'error', msg: res?.message || 'Failed' }
      }
    } catch (e) {
      u._result = { status: 'error', msg: e?.data?.message || e?.message || 'Failed' }
    }
  }
  sending.value = false
}
</script>

<template>
  <div class="modal" :class="{ active: modelValue }" :style="{ display: modelValue ? 'block' : 'none' }">
    <div class="modalDialog modalCenter" @click.self="close">
      <div class="modalContent" style="max-width: 640px;">
        <div class="modalHeader">
          <h3 class="modalTitle">{{ t('Zugangsdaten senden', 'Send login data') }}<span v-if="bpartnerName" class="ml-2" style="color:#94a3b8;font-weight:400;font-size:0.85rem;"> · {{ bpartnerName }}</span></h3>
          <div class="cursor-pointer" @click="close"><span class="tf-icon ti ti-x ti-sm"></span></div>
        </div>
        <div class="modalBody">
          <div class="mx-5 my-4">
            <p class="ml-0 mb-3" style="font-size: 0.86rem; color: #555;">
              {{ t('Wählen Sie die Benutzer, die ihre Zugangsdaten per E-Mail erhalten sollen.', 'Select the users who should receive their login details by e-mail.') }}
            </p>

            <div v-if="loading" class="sml-empty"><span class="ti ti-loader spin"></span> {{ t('Lädt…', 'Loading…') }}</div>
            <div v-else-if="error" class="sml-err">{{ error }}</div>
            <div v-else-if="!users.length" class="sml-empty">{{ t('Keine Benutzer gefunden.', 'No users found.') }}</div>

            <template v-else>
              <div class="sml-toolbar">
                <label class="sml-check"><input type="checkbox" v-model="allSelected" /> {{ t('Alle', 'All') }}</label>
                <label class="sml-check"><input type="checkbox" v-model="showPasswords" /> {{ t('Passwörter zeigen', 'Show passwords') }}</label>
                <label class="sml-check sml-check--reset"><input type="checkbox" v-model="resetPasswords" /> {{ t('Passwort zurücksetzen', 'Reset password') }}</label>
                <span class="sml-count">{{ selectedCount }} {{ t('ausgewählt', 'selected') }}</span>
              </div>

              <div class="sml-list">
                <div v-for="u in users" :key="u.id" class="sml-row" :class="{ 'sml-row--sel': u._selected }">
                  <input type="checkbox" v-model="u._selected" class="sml-row-check" />
                  <div class="sml-row-main">
                    <div class="sml-row-top">
                      <span class="sml-user">{{ u.username || ('#' + u.id) }}</span>
                      <span v-if="!u.hasPassword" class="sml-badge">{{ t('kein Passwort', 'no password') }}</span>
                      <span v-if="u._result" class="sml-res" :class="u._result.status">{{ u._result.msg || u._result.status }}</span>
                    </div>
                    <div class="sml-row-fields">
                      <input type="email" v-model="u._email" class="input sml-email" :placeholder="t('E-Mail', 'e-mail')" />
                      <span v-if="u.hasPassword" class="sml-pw">{{ showPasswords ? u.password : '••••••••' }}</span>
                    </div>
                  </div>
                </div>
              </div>
              <p v-if="resetPasswords" class="sml-note sml-note--reset">{{ t('Für jeden ausgewählten Benutzer wird ein neues 8-stelliges Passwort generiert, in iDempiere gespeichert und per E-Mail gesendet.', 'A new 8-character password is generated, saved in iDempiere and e-mailed for each selected user.') }} {{ LOGIN_URL }}</p>
              <p v-else class="sml-note">{{ t('Hinweis: Benutzer ohne Passwort erhalten nur Benutzername und Login-Link.', 'Note: users without a password receive only the username and login link.') }} {{ LOGIN_URL }}</p>
            </template>
          </div>
        </div>
        <div class="modalFooter">
          <button type="button" class="button" @click="close">{{ t('Schließen', 'Close') }}</button>
          <button type="button" class="button is-primary" @click="send" :class="{ 'pointerEvents-none opacity-0.6': !canSend }">
            <span v-if="sending" class="ti ti-loader spin me-1"></span>
            {{ sending ? t('Senden…', 'Sending…') : t('An Auswahl senden', 'Send to selected') }}
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.sml-empty, .sml-err { padding: 18px; text-align: center; font-size: 0.88rem; }
.sml-err { color: #b91c1c; }
.sml-toolbar { display: flex; align-items: center; gap: 18px; padding: 6px 2px 10px; border-bottom: 1px solid var(--theme-border, #e5e7eb); margin-bottom: 8px; }
.sml-check { display: inline-flex; align-items: center; gap: 6px; font-size: 0.82rem; color: #475569; cursor: pointer; }
.sml-count { margin-left: auto; font-size: 0.8rem; color: #94a3b8; }
.sml-list { max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.sml-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--theme-border, #e5e7eb); border-radius: 10px; }
.sml-row--sel { border-color: #93c5fd; background: #f5f9ff; }
.sml-row-check { margin-top: 4px; }
.sml-row-main { flex: 1; min-width: 0; }
.sml-row-top { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.sml-user { font-weight: 600; font-size: 0.9rem; }
.sml-badge { font-size: 0.68rem; background: #fef3c7; color: #92400e; padding: 1px 7px; border-radius: 999px; }
.sml-res { font-size: 0.72rem; padding: 1px 8px; border-radius: 999px; margin-left: auto; }
.sml-res.ok { background: #d1fae5; color: #065f46; }
.sml-res.error { background: #fee2e2; color: #991b1b; }
.sml-res.sending { background: #e0e7ff; color: #3730a3; }
.sml-row-fields { display: flex; align-items: center; gap: 10px; }
.sml-email { flex: 1; min-width: 0; }
.sml-pw { font-family: monospace; font-size: 0.8rem; color: #475569; white-space: nowrap; }
.sml-check--reset { color: #b45309; font-weight: 600; }
.sml-note { font-size: 0.74rem; color: #94a3b8; margin-top: 10px; }
.sml-note--reset { color: #b45309; background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px; padding: 8px 10px; }
.spin { animation: smlspin 1s linear infinite; display: inline-block; }
@keyframes smlspin { to { transform: rotate(360deg); } }
</style>
