<template>
  <q-dialog ref="dialogRef" @hide="onDialogHide">
    <q-card
      class="q-dialog-plugin dialog-form-card"
      style="width: 100%; max-width: 900px"
    >
      <DefaultDialogHeader
        :title="
          props.responsible
            ? 'Editar Responsável'
            : 'Novo Responsável'
        "
        @close="onDialogCancel"
      />

      <DefaultForm
        ref="formRef"
        @submit="handleSave"
      >
        <q-scroll-area
          class="dialog-form-scroll"
          style="height: 65vh"
        >
          <q-card-section class="q-pt-sm">
            <div class="row q-col-gutter-sm">
              <DefaultInput
                v-model="form.name"
                class="col-6"
                label="Nome"
                :error="!!validationErrors.name"
                :error-message="validationErrors.name"
                :rules="[inputRules.required]"
              />

              <DefaultInput
                v-model="form.degree"
                class="col-6"
                label="Grau de Parentesco"
                :error="!!validationErrors.degree"
                :error-message="validationErrors.degree"
                :rules="[inputRules.required]"
              />

              <DefaultInputDatePicker
                v-model="form.birth_date"
                class="col-4"
                label="Data de Nascimento"
                :error="!!validationErrors.birth_date"
                :error-message="validationErrors.birth_date"
                :rules="[inputRules.required]"
              />

              <DefaultInput
                v-model="form.cpf"
                class="col-4"
                label="CPF"
                :error="!!validationErrors.cpf"
                :error-message="validationErrors.cpf"
                :mask="masks.Brasil.cpf"
                :rules="[inputRules.required, inputRules.cpf]"
              />

              <DefaultSelect
                v-model="form.gender"
                class="col-4"
                emit-value
                label="Gênero"
                map-options
                :error="!!validationErrors.gender"
                :error-message="validationErrors.gender"
                :options="genderOptions"
              />

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

              <DefaultInput
                v-model="form.phone"
                class="col-6"
                label="Telefone"
                :error="!!validationErrors.phone"
                :error-message="validationErrors.phone"
                :mask="masks.Brasil.celular"
                :rules="[inputRules.required]"
              />

              <DefaultCepInput
                v-model="form.postal_code"
                class="col-4"
                :error="!!validationErrors.postal_code"
                :error-message="validationErrors.postal_code"
                :rules="[inputRules.required, inputRules.cep]"
                @bairro="
                  (value) =>
                    (form.neighborhood = value)
                "
                @cidade="
                  (value) =>
                    citySelectRef?.selectCityByName(value)
                "
                @rua="
                  (value) =>
                    (form.street = value)
                "
                @uf="
                  (value) =>
                    stateSelectRef?.selectStateByCode(value)
                "
              />

              <DefaultInput
                v-model="form.street"
                class="col-5"
                label="Endereço"
                :error="!!validationErrors.street"
                :error-message="validationErrors.street"
                :rules="[inputRules.required]"
              />

              <DefaultInput
                v-model="form.address_number"
                class="col-3"
                label="Número"
                :error="!!validationErrors.address_number"
                :error-message="validationErrors.address_number"
              />

              <DefaultInput
                v-model="form.neighborhood"
                class="col-4"
                label="Bairro"
                :error="!!validationErrors.neighborhood"
                :error-message="validationErrors.neighborhood"
                :rules="[inputRules.required]"
              />

              <CitySelect
                ref="citySelectRef"
                v-model="selectedCity"
                class="col-4"
                label="Cidade"
                :error="!!validationErrors.city_id"
                :error-message="validationErrors.city_id"
                :initial-id="props.responsible?.city_id ?? null"
                :rules="[inputRules.required]"
                :state="selectedState"
              />

              <StateSelect
                ref="stateSelectRef"
                v-model="selectedState"
                class="col-4"
                label="Estado"
                :error="!!validationErrors.state_id"
                :error-message="validationErrors.state_id"
                :initial-id="props.responsible?.state_id ?? null"
                :rules="[inputRules.required]"
              />

              <DefaultInput
                v-model="form.complement"
                class="col-12"
                label="Complemento"
                :error="!!validationErrors.complement"
                :error-message="validationErrors.complement"
              />

              <DefaultInput
                v-model="form.notes"
                autogrow
                class="col-12"
                label="Observações"
                type="textarea"
                :error="!!validationErrors.notes"
                :error-message="validationErrors.notes"
                :input-style="{ minHeight: '120px' }"
              />
            </div>
          </q-card-section>
        </q-scroll-area>

        <q-card-actions
          align="right"
          class="q-px-md q-pb-md"
        >
          <q-btn
            color="primary"
            label="Cancelar"
            no-caps
            outline
            @click="onDialogCancel"
          />

          <q-btn
            color="primary"
            label="Salvar"
            no-caps
            type="submit"
            :loading="saving"
          />
        </q-card-actions>
      </DefaultForm>
    </q-card>
  </q-dialog>
</template>

<script setup>
import {
  createStudentResponsible,
  updateStudentResponsible,
} from "src/api/studentResponsible";

import {
  formatDateDMYtoYMD,
  formatDateYMDtoDMY,
} from "src/helpers/utils";

import { ref, useTemplateRef, watch } from "vue";
import { useDialogPluginComponent } from "quasar";
import { useForm } from "src/composables/useForm";
import { useInputRules } from "src/composables/useInputRules";
import { useSubmitHandler } from "src/composables/useSubmitHandler";

import masks from "src/helpers/masks";

import DefaultCepInput from "src/components/defaults/DefaultCepInput.vue";
import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
import DefaultForm from "src/components/defaults/DefaultForm.vue";
import DefaultInput from "src/components/defaults/DefaultInput.vue";
import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
import CitySelect from "src/components/selects/CitySelect.vue";
import StateSelect from "src/components/selects/StateSelect.vue";

defineEmits([...useDialogPluginComponent.emits]);

const props = defineProps({
  responsible: {
    type: Object,
    default: null,
  },
  studentId: {
    type: Number,
    required: true,
  },
});

const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  useDialogPluginComponent();

const { inputRules } = useInputRules();

const citySelectRef = useTemplateRef("citySelectRef");
const formRef = useTemplateRef("formRef");
const stateSelectRef = useTemplateRef("stateSelectRef");

const selectedCity = ref(null);
const selectedState = ref(null);

const genderOptions = [
  {
    label: "Masculino",
    value: "male",
  },
  {
    label: "Feminino",
    value: "female",
  },
  {
    label: "Outro",
    value: "other",
  },
  {
    label: "Prefiro não informar",
    value: "no_preference",
  },
];

const initialForm = props.responsible
  ? {
      address_number:
        props.responsible.address_number ?? null,

      birth_date: props.responsible.birth_date
        ? formatDateYMDtoDMY(
            props.responsible.birth_date,
          )
        : null,

      city_id: props.responsible.city_id ?? null,
      complement: props.responsible.complement ?? null,
      cpf: props.responsible.cpf ?? null,
      degree: props.responsible.degree ?? null,
      email: props.responsible.email ?? null,

      gender:
        props.responsible.gender ?? "no_preference",

      name: props.responsible.name ?? null,

      neighborhood:
        props.responsible.neighborhood ?? null,

      notes: props.responsible.notes ?? null,
      phone: props.responsible.phone ?? null,

      postal_code:
        props.responsible.postal_code ?? null,

      state_id: props.responsible.state_id ?? null,
      street: props.responsible.street ?? null,
    }
  : {
      address_number: null,
      birth_date: null,
      city_id: null,
      complement: null,
      cpf: null,
      degree: null,
      email: null,
      gender: "no_preference",
      name: null,
      neighborhood: null,
      notes: null,
      phone: null,
      postal_code: null,
      state_id: null,
      street: null,
    };

const { form, getUpdatedFields } = useForm(initialForm);

const {
  loading: saving,
  validationErrors,
  execute,
} = useSubmitHandler({
  formRef,
  onSuccess: () => {
    onDialogOK(true);
  },
});

const buildPayload = () => ({
  address_number: form.address_number,

  birth_date: form.birth_date
    ? formatDateDMYtoYMD(form.birth_date)
    : null,

  city_id: form.city_id,
  complement: form.complement,
  cpf: form.cpf,
  degree: form.degree,
  email: form.email,
  gender: form.gender,
  name: form.name,
  neighborhood: form.neighborhood,
  notes: form.notes,
  phone: form.phone,
  postal_code: form.postal_code,
  state_id: form.state_id,
  street: form.street,
  student_id: props.studentId,
});

const handleSave = async () => {
  const payload = buildPayload();

  await execute(() => {
    if (!props.responsible) {
      return createStudentResponsible(payload);
    }

    const changedFields = {
      ...getUpdatedFields.value,
    };

    const updatePayload = {};

    for (const key of Object.keys(payload)) {
      if (
        key !== "student_id" &&
        key !== "birth_date" &&
        key in changedFields
      ) {
        updatePayload[key] = payload[key];
      }
    }

    if ("birth_date" in changedFields) {
      updatePayload.birth_date = payload.birth_date;
    }

    return updateStudentResponsible(
      props.responsible.id,
      updatePayload,
    );
  });
};

watch(selectedState, (state) => {
  form.state_id = state?.value ?? null;
});

watch(selectedCity, (city) => {
  form.city_id = city?.value ?? null;
});
</script>
