<template>
  <q-card-section class="no-padding">
    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("auth.full_name") }}
        </span>
      </div>

      <q-input
        v-model="form.name"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        no-error-icon
        outlined
        rounded
        :error="!!serverErrors.name"
        :error-message="serverErrors.name"
        :placeholder="$t('auth.full_name')"
        :rules="[inputRules.required]"
        @update:model-value="clearServerError('name')"
      />
    </div>

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("common.terms.document") }}
        </span>
      </div>

      <q-input
        v-model="form.document"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        no-error-icon
        outlined
        rounded
        :error="!!serverErrors.document"
        :error-message="serverErrors.document"
        :placeholder="$t('common.terms.document')"
        :rules="[inputRules.cpfOrCnpj]"
        @update:model-value="clearServerError('document')"
      />
    </div>

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("common.terms.phone") }}
        </span>
      </div>

      <q-input
        v-model="form.phone"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        mask="(##) #####-####"
        no-error-icon
        outlined
        rounded
        :error="!!serverErrors.phone"
        :error-message="serverErrors.phone"
        :placeholder="$t('common.terms.phone')"
        :rules="[inputRules.required, inputRules.phone]"
        @update:model-value="clearServerError('phone')"
      />
    </div>

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("common.terms.cep") }}
        </span>
      </div>

      <q-input
        v-model="form.zip_code"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        mask="#####-###"
        no-error-icon
        outlined
        placeholder="00000-000"
        rounded
        :error="!!serverErrors.zip_code"
        :error-message="serverErrors.zip_code"
        :loading="loadingCep"
        :rules="[inputRules.required, inputRules.cep]"
        @update:model-value="(clearServerError('zip_code'), onCepChange($event))"
      />
    </div>

    <q-btn
      class="full-width q-mb-md"
      color="primary-button"
      padding="8px 12px"
      rounded
      :label="$t('auth.use_location')"
      :loading="loadingLocation"
      @click="useLocation"
    />

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("common.terms.address") }}
        </span>
      </div>

      <q-input
        v-model="form.address"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        no-error-icon
        outlined
        readonly
        rounded
        :error="!!serverErrors.address"
        :error-message="serverErrors.address"
        :placeholder="`${$t('common.terms.address')}...`"
        :rules="[inputRules.required]"
      />
    </div>

    <div class="row q-col-gutter-sm">
      <div class="col-4">
        <div class="text-text">
          <span class="font14 fontbold">
            {{ $t("common.terms.address_number") }}
          </span>
        </div>

        <q-input
          v-model="form.number"
          bg-color="surface"
          class="q-mt-sm q-mb-md"
          hide-bottom-space
          input-class="text-text"
          lazy-rules
          no-error-icon
          outlined
          placeholder="0000"
          rounded
          :error="!!serverErrors.number"
          :error-message="serverErrors.number"
          :rules="[inputRules.required]"
          @update:model-value="clearServerError('number')"
        />
      </div>

      <div class="col-8">
        <div class="text-text">
          <span class="font14 fontbold">
            {{ $t("common.terms.district") }}
          </span>
        </div>

        <q-input
          v-model="form.district"
          bg-color="surface"
          class="q-mt-sm q-mb-md"
          hide-bottom-space
          input-class="text-text"
          lazy-rules
          no-error-icon
          outlined
          readonly
          rounded
          :error="!!serverErrors.district"
          :error-message="serverErrors.district"
          :placeholder="`${$t('common.terms.district')}...`"
          :rules="[inputRules.required]"
        />
      </div>
    </div>

    <div class="row q-col-gutter-sm">
      <div class="col-8">
        <div class="text-text">
          <span class="font14 fontbold">
            {{ $t("common.terms.city") }}
          </span>
        </div>

        <q-input
          v-model="form.city"
          bg-color="surface"
          class="q-mt-sm q-mb-md"
          hide-bottom-space
          input-class="text-text"
          lazy-rules
          no-error-icon
          outlined
          readonly
          rounded
          :error="!!serverErrors.city"
          :error-message="serverErrors.city"
          :rules="[inputRules.required]"
        />
      </div>

      <div class="col-4">
        <div class="text-text">
          <span class="font14 fontbold">
            {{ $t("common.terms.state") }}
          </span>
        </div>

        <q-input
          v-model="form.state"
          bg-color="surface"
          class="q-mt-sm q-mb-md"
          hide-bottom-space
          input-class="text-text"
          lazy-rules
          no-error-icon
          outlined
          readonly
          rounded
          :error="!!serverErrors.state"
          :error-message="serverErrors.state"
          :rules="[inputRules.required]"
        />
      </div>
    </div>

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("common.terms.complement") }}
        </span>
      </div>

      <q-input
        v-model="form.complement"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        no-error-icon
        outlined
        rounded
        :error="!!serverErrors.complement"
        :error-message="serverErrors.complement"
        :placeholder="`${$t('common.ui.misc.example')}: Apartamento, Conjunto, Casa`"
        :rules="[inputRules.required]"
        @update:model-value="clearServerError('complement')"
      />
    </div>

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("auth.address_nickname") }}
        </span>
      </div>

      <q-input
        v-model="form.nickname"
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        no-error-icon
        outlined
        rounded
        :placeholder="`${$t('common.ui.misc.example')}: Casa`"
      />
    </div>

    <div>
      <div class="text-text">
        <span class="font14 fontbold">
          {{ $t("auth.address_instructions") }}
        </span>
      </div>

      <q-input
        v-model="form.instructions"
        autogrow
        bg-color="surface"
        class="q-mt-sm q-mb-md"
        hide-bottom-space
        input-class="text-text"
        lazy-rules
        no-error-icon
        outlined
        rounded
        rows="3"
        type="textarea"
      />
    </div>

    <div>
      <div class="row q-gutter-sm q-mt-xs">
        <q-chip
          v-for="type in addressTypes"
          :key="type.value"
          :icon="type.icon"
          :icon-selected="type.icon"
          :outline="form.address_type !== type.value"
          :selected="form.address_type === type.value"
          clickable
          color="primary"
          text-color="surface"
          @click="form.address_type = type.value"
        >
          {{ $t(type.label) }}
        </q-chip>
      </div>
    </div>
  </q-card-section>
</template>

<script setup>
import axios from "axios";

import { inject, ref } from "vue";
import { useGeolocation } from "src/composables/useGeolocation";
import { useI18n } from "vue-i18n";
import { useInputRules } from "src/composables/useInputRules";
import { useQuasar } from "quasar";

import LocationMapDialog from "src/components/shared/LocationMapDialog.vue";

const form = defineModel({
  required: true,
  type: Object,
});

defineProps({
  serverErrors: {
    type: Object,
    default: () => ({}),
  },
});

const clearServerError = inject("clearServerError", () => {});

const { requestPermission, getCurrentPosition } = useGeolocation();
const { inputRules } = useInputRules();
const { t } = useI18n();

const $q = useQuasar();

const loadingCep = ref(false);
const loadingLocation = ref(false);

const addressTypes = [
  {
    icon: "mdi-home-outline",
    label: "auth.address_type_home",
    value: "home",
  },
  {
    icon: "mdi-briefcase-variant-outline",
    label: "auth.address_type_commercial",
    value: "commercial",
  },
  {
    icon: "mdi-map-marker-outline",
    label: "auth.address_type_other",
    value: "other",
  },
];

const fetchCep = async (rawCep) => {
  const cleaned = rawCep.replace(/\D/g, "");

  if (cleaned.length !== 8) {
    return;
  }

  loadingCep.value = true;

  try {
    const { data } = await axios.get(
      `https://viacep.com.br/ws/${cleaned}/json/`,
    );

    if (!data.erro) {
      form.value.address = data.logradouro ?? "";
      form.value.district = data.bairro ?? "";
      form.value.city = data.localidade ?? "";
      form.value.state = data.uf ?? "";
    } else {
      form.value.address = "";
      form.value.district = "";
      form.value.city = "";
      form.value.state = "";
    }
  } catch {
    form.value.address = "";
    form.value.district = "";
    form.value.city = "";
    form.value.state = "";
  } finally {
    loadingCep.value = false;
  }
};

const onCepChange = (val) => {
  const cleaned = val ? val.replace(/\D/g, "") : "";

  form.value.latitude = null;
  form.value.longitude = null;

  if (cleaned.length === 8) {
    fetchCep(val);
  } else {
    form.value.address = "";
    form.value.district = "";
    form.value.city = "";
    form.value.state = "";
  }
};

const showCurrentLocationOnMap = ({ lat, lng }) => {
  $q.dialog({
    component: LocationMapDialog,
    componentProps: {
      initialLat: lat,
      initialLng: lng,
    },
  }).onOk((geoData) => {
    form.value.zip_code = geoData.zip_code ?? "";
    form.value.address = geoData.address ?? "";
    form.value.number = geoData.number ?? "";
    form.value.district = geoData.district ?? "";
    form.value.city = geoData.city ?? "";
    form.value.state = geoData.state ?? "";
    form.value.latitude = geoData.lat;
    form.value.longitude = geoData.lng;
  });
};

const useLocation = async () => {
  loadingLocation.value = true;

  try {
    const granted = await requestPermission();

    if (!granted) {
      $q.notify({
        message: t("auth.location_permission_denied"),
        type: "warning",
      });

      return;
    }

    const position = await getCurrentPosition();

    showCurrentLocationOnMap(position);
  } catch (err) {
    const isPermissionError =
      err?.code === 1 || err?.message?.toLowerCase().includes("denied");

    $q.notify({
      message: isPermissionError
        ? t("auth.location_permission_denied")
        : t("auth.location_error"),
      type: "warning",
    });
  } finally {
    loadingLocation.value = false;
  }
};
</script>
