<template>
  <div>
    <DefaultHeaderPage
      :title="isEdit ? 'Editar Usuário' : 'Cadastro de Usuário'"
    />

    <div class="q-pa-md">
      <q-form ref="formRef">
        <div class="column justify-center items-center q-mb-lg">
          <AvatarImageComponent
            ref="avatarRef"
            @update:file="(f) => (avatarFile = f)"
          />

          <div class="row full-width q-mt-md q-col-gutter-sm">
            <div class="col-12">
              <q-btn-toggle
                v-model="form.access_scope"
                spread
                no-caps
                toggle-color="primary"
                :options="[
                  { label: 'Acesso de unidade', value: 'unit' },
                  { label: 'Acesso franqueadora', value: 'franchisor' },
                ]"
              />
            </div>
            <StateSelect
              v-if="form.access_scope === 'unit'"
              v-model="form.state"
              class="col-3"
              outlined
              label="Estado / UF"
              :initial-id="editStateId"
            />

            <UnitMultiSelect
              v-if="form.access_scope === 'unit'"
              v-model="form.units"
              class="col-9"
              outlined
              label="Unidades"
              :initial-ids="editUnitIds"
            />

            <UserTypeSelect
              :key="form.access_scope"
              v-model="form.user_type"
              :access-scope="form.access_scope"
              :unit-id="selectedUnitId"
              class="col-6"
              outlined
              label="Tipo de Usuário"
              :rules="[inputRules.required]"
            />

            <DefaultInput
              v-model="form.cpf"
              label="CPF"
              class="col-6"
              outlined
              mask="###.###.###-##"
              :rules="[inputRules.cpf]"
            />

            <DefaultInput
              v-model="form.name"
              label="Nome"
              class="col-6"
              outlined
              :rules="[inputRules.required]"
            />

            <DefaultInput
              v-model="form.email"
              label="E-mail"
              class="col-6"
              outlined
              type="email"
              :rules="[inputRules.required, inputRules.email]"
            />

            <DefaultInput
              v-model="form.password"
              label="Senha"
              class="col-6"
              outlined
              :type="showPassword ? 'text' : 'password'"
              :rules="
                isEdit
                  ? [(v) => !v || v.length >= 8 || 'Mínimo 8 caracteres']
                  : [inputRules.required, inputRules.min(8)]
              "
            >
              <template #append>
                <q-icon
                  :name="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
                  class="cursor-pointer"
                  color="secondary"
                  @click="showPassword = !showPassword"
                />
              </template>
            </DefaultInput>

            <DefaultInput
              v-model="form.password_confirmation"
              label="Repetir Senha"
              class="col-6"
              outlined
              :type="showPasswordConfirm ? 'text' : 'password'"
              :rules="
                isEdit
                  ? [
                      (v) =>
                        !form.password ||
                        v === form.password ||
                        'Senhas não conferem',
                    ]
                  : [
                      inputRules.required,
                      inputRules.samePassword(form.password),
                    ]
              "
            >
              <template #append>
                <q-icon
                  :name="showPasswordConfirm ? 'mdi-eye-off' : 'mdi-eye'"
                  class="cursor-pointer"
                  color="secondary"
                  @click="showPasswordConfirm = !showPasswordConfirm"
                />
              </template>
            </DefaultInput>

            <div v-if="isEdit" class="col-12 text-caption text-grey-6">
              Deixe os campos de senha em branco para manter a senha atual.
            </div>

            <div class="col-6 flex items-center">
              <q-btn
                label="Gerar senha segura"
                icon="mdi-thumb-up-outline"
                color="primary"
                @click="generatePassword"
              />
            </div>
          </div>

          <div class="row justify-end q-mt-md full-width">
            <q-btn
              v-if="canSave"
              label="SALVAR"
              icon-right="mdi-check"
              color="primary"
              :loading="loading"
              @click="onSave"
            />
          </div>
        </div>
      </q-form>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import AvatarImageComponent from "src/components/shared/AvatarImageComponent.vue";
import StateSelect from "src/components/selects/StateSelect.vue";
import UnitMultiSelect from "src/components/selects/UnitMultiSelect.vue";
import UserTypeSelect from "src/components/selects/UserTypeSelect.vue";
import { useInputRules } from "src/composables/useInputRules";
import { useSubmitHandler } from "src/composables/useSubmitHandler";
import { createUser, updateUser, getUserById } from "src/api/user";
import { permissionStore } from "src/stores/permission";

const router = useRouter();
const route = useRoute();
const { inputRules } = useInputRules();

const formRef = ref(null);
const avatarRef = ref(null);
const avatarFile = ref(null);

const showPassword = ref(false);
const showPasswordConfirm = ref(false);

const editStateId = ref(null);
const editUnitIds = ref([]);
const loadingUser = ref(false);

const isEdit = computed(() => !!route.params.id);
const permissions = permissionStore();
const canSave = computed(() =>
  permissions.getAccess(
    "franchisor_registrations",
    isEdit.value ? "edit" : "add",
  ),
);
const selectedUnitId = computed(() => form.value.units?.[0]?.value ?? null);

const form = ref({
  access_scope: "unit",
  state: null,
  units: [],
  user_type: null,
  cpf: null,
  name: null,
  email: null,
  password: null,
  password_confirmation: null,
});

const { loading, execute } = useSubmitHandler({
  formRef,
  onSuccess: () => {
    router.push({ name: "CadastrosPage" });
  },
});

onMounted(async () => {
  if (!isEdit.value) return;
  loadingUser.value = true;
  try {
    const user = await getUserById(route.params.id);
    form.value.name = user.name;
    form.value.email = user.email;
    form.value.cpf = user.cpf;
    form.value.user_type = user.user_type;
    form.value.access_scope = user.access_scope ?? (user.units?.length ? "unit" : "franchisor");
    editStateId.value = user.state_id ?? null;
    editUnitIds.value = user.units?.map((u) => u.id) ?? [];
    if (user.avatar_url) {
      avatarRef.value?.setImageUrl(user.avatar_url);
    }
  } catch (error) {
    console.error("Failed to load user:", error);
  } finally {
    loadingUser.value = false;
  }
});

function buildFormData() {
  const fd = new FormData();

  if (avatarFile.value) fd.append("avatar", avatarFile.value);
  fd.append("access_scope", form.value.access_scope);
  if (form.value.state?.value) fd.append("state_id", form.value.state.value);
  form.value.units?.forEach((u) => fd.append("unit_ids[]", u.value));
  if (form.value.user_type) fd.append("user_type", form.value.user_type);
  if (form.value.cpf) fd.append("cpf", form.value.cpf);

  fd.append("name", form.value.name ?? "");
  fd.append("email", form.value.email ?? "");
  fd.append("password", form.value.password ?? "");

  return fd;
}

function buildUpdateData() {
  const fd = new FormData();
  fd.append("_method", "PUT");

  if (avatarFile.value) fd.append("avatar", avatarFile.value);
  fd.append("access_scope", form.value.access_scope);
  if (form.value.state?.value) fd.append("state_id", form.value.state.value);
  // Sempre envia unit_ids[] para sincronizar (array vazio limpa todas as unidades)
  (form.value.units ?? []).forEach((u) => fd.append("unit_ids[]", u.value));
  if (form.value.user_type) fd.append("user_type", form.value.user_type);
  if (form.value.cpf) fd.append("cpf", form.value.cpf);
  if (form.value.name) fd.append("name", form.value.name);
  if (form.value.email) fd.append("email", form.value.email);
  if (form.value.password) fd.append("password", form.value.password);

  return fd;
}

async function onSave() {
  if (isEdit.value) {
    await execute(() => updateUser(buildUpdateData(), route.params.id));
  } else {
    await execute(() => createUser(buildFormData()));
  }
}

function generatePassword() {
  const chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%";
  const password = Array.from({ length: 12 }, () =>
    chars.charAt(Math.floor(Math.random() * chars.length)),
  ).join("");
  form.value.password = password;
  form.value.password_confirmation = password;
}

watch(
  () => form.value.access_scope,
  (scope, previousScope) => {
    if (previousScope && !loadingUser.value) form.value.user_type = null;
    if (scope === "franchisor") {
      form.value.state = null;
      form.value.units = [];
    }
  },
  { flush: "sync" },
);
</script>
