<template>
  <q-dialog v-model="isOpen">
    <q-card class="password-card modal-card">
      <q-card-section>
        <div class="text-overline text-primary">Change password</div>
        <div class="text-h6">{{ userEmail || 'User' }}</div>
      </q-card-section>

      <q-separator />

      <q-card-section class="password-grid">
        <q-input
          v-model="formModel.password"
          outlined
          type="password"
          label="New password"
          hint="Minimo 8 caratteri"
        />
        <q-input
          v-model="formModel.confirmPassword"
          outlined
          type="password"
          label="Confirm password"
        />
      </q-card-section>

      <q-card-actions align="right">
        <q-btn flat color="grey-7" label="Chiudi" @click="isOpen = false" />
        <q-btn color="primary" label="Salva password" :loading="saving" @click="savePasswordChange" />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import { useQuasar } from 'quasar';

import { getUser, updatePassword } from 'src/api/users';

import type { PasswordFormState } from './types';

const props = defineProps<{
  modelValue: boolean;
  userId?: string;
}>();

const emit = defineEmits<{
  'update:modelValue': [value: boolean];
  saved: [];
}>();

const $q = useQuasar();
const saving = ref(false);
const userEmail = ref('');
const formModel = reactive<PasswordFormState>({
  password: '',
  confirmPassword: '',
});

const isOpen = computed({
  get: () => props.modelValue,
  set: (value: boolean) => emit('update:modelValue', value),
});

watch(
  () => [props.modelValue, props.userId] as const,
  ([open, userId]) => {
    if (!open || !userId) {
      return;
    }

    void prepareDialog(userId);
  },
  { immediate: true },
);

async function prepareDialog(userId: string): Promise<void> {
  try {
    const response = await getUser(userId);
    if (response.error) {
      throw new Error(response.error);
    }

    userEmail.value = response.data.email;
    formModel.password = '';
    formModel.confirmPassword = '';
  } catch (error) {
    notifyError(error);
    isOpen.value = false;
  }
}

async function savePasswordChange(): Promise<void> {
  if (!props.userId) {
    $q.notify({ type: 'negative', message: 'ID utente mancante.' });
    return;
  }

  if (formModel.password.trim().length < 8) {
    $q.notify({ type: 'negative', message: 'La password deve contenere almeno 8 caratteri.' });
    return;
  }

  if (formModel.password !== formModel.confirmPassword) {
    $q.notify({ type: 'negative', message: 'Le password non coincidono.' });
    return;
  }

  saving.value = true;
  try {
    const response = await updatePassword({
      id: props.userId,
      password: formModel.password,
    });
    if (response.error) {
      throw new Error(response.error);
    }

    isOpen.value = false;
    $q.notify({ type: 'positive', message: `Password aggiornata per ${userEmail.value || 'utente'}.` });
    emit('saved');
  } catch (error) {
    notifyError(error);
  } finally {
    saving.value = false;
  }
}

function notifyError(error: unknown): void {
  $q.notify({
    type: 'negative',
    message: error instanceof Error ? error.message : String(error),
  });
}
</script>

<style scoped>
.modal-card {
  width: min(96vw, 460px);
  max-width: 460px;
}

.password-card {
  border-radius: 20px;
}

.password-grid {
  display: grid;
  gap: 14px;
}
</style>
