<!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
<template>
  <q-page class="login-page bg-surface-dark">
    <Transition mode="out-in" name="fade-slide">
      <div
        v-if="!clicked"
        key="splash"
        class="splash-screen"
        @click="clicked = true"
      >
        <img class="splash-layer splash-layer--bg" :src="BackgroundLogin" />

        <img class="splash-layer splash-layer--photo" :src="FotoDiarista" />

        <img class="splash-layer splash-layer--logo" :src="LogoLogin" />
      </div>

      <div v-else key="flow" class="flow-screen">
        <div
          v-if="!showSubStep"
          class="flow-header row items-center"
        >
          <q-btn
            v-if="steps >= 4"
            class="flow-back-btn"
            color="primary"
            dense
            flat
            icon="mdi-arrow-left"
            round
            @click="goBack"
          />
        </div>

        <div v-if="!showSubStep" class="flow-logo q-my-xl">
          <q-img style="max-width: 180px" :src="LogoDiariaCampos" />
        </div>

        <q-form
          v-if="!registrationCompleted"
          ref="loginForm"
          autocapitalize="off"
          autocomplete="off"
          autocorrect="off"
          class="flow-form"
          spellcheck="false"
          @submit="onSubmit"
        >
          <div
            class="flow-content"
            :class="{ 'flow-content--centered': steps <= 2 && !showSubStep }"
          >
            <LoginStep1Panel
              v-if="steps === 1"
              v-model:email="email"
              v-model:phone="phone"
            />

            <LoginStep2Panel v-else-if="steps === 2" v-model:code="code" />

            <LoginStep3Panel
              v-else-if="steps === 3"
              v-model="stepThreeForm"
            />

            <LoginStep4Panel
              v-else-if="steps === 4"
              v-model="stepFourForm"
              @update:show-sub-step="showSubStep = $event"
            />

            <LoginStep5Panel
              v-else-if="steps === 5"
              v-model="stepFiveForm"
            />

            <LoginStep6Panel v-else-if="steps === 6" v-model="stepSixForm" />
          </div>

          <div v-if="!showSubStep" class="flow-footer">
            <q-btn
              class="full-width"
              color="primary-button"
              padding="8px 16px"
              rounded
              type="submit"
              :label="actionLabel"
              :loading="submitting"
            >
              <template #loading>
                <q-spinner />
              </template>
            </q-btn>
          </div>
        </q-form>

        <div v-else class="registration-complete">
          <q-icon
            class="q-mb-md"
            color="positive"
            name="mdi-check-circle-outline"
            size="52px"
          />

          <div class="registration-complete__title text-text fontbold">
            {{ t("provider.login.registration_complete.title") }}
          </div>

          <div class="registration-complete__message text-grey-7 font12">
            {{ t("provider.login.registration_complete.message") }}
          </div>
        </div>
      </div>
    </Transition>
  </q-page>
</template>

<script setup>
import { computed, onMounted, ref } from "vue";
import { createUserAndProvider, sendCode, validateCode } from "src/api/user";
import { useAuth } from "src/composables/useAuth";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";

import BackgroundLogin from "src/assets/background-login.svg";
import FotoDiarista from "src/assets/foto_diarista_login.svg";
import LogoDiariaCampos from "src/assets/logo_diaria_campos_login.svg";
import LogoLogin from "src/assets/logo_diaria_login.svg";
import LoginStep1Panel from "src/components/login/LoginStep1Panel.vue";
import LoginStep2Panel from "src/components/login/LoginStep2Panel.vue";
import LoginStep3Panel from "src/components/login/LoginStep3Panel.vue";
import LoginStep4Panel from "src/components/login/LoginStep4Panel.vue";
import LoginStep5Panel from "src/components/login/LoginStep5Panel.vue";
import LoginStep6Panel from "src/components/login/LoginStep6Panel.vue";

const $q = useQuasar();
const router = useRouter();
const { setAuthDataFromPayload } = useAuth();
const { t } = useI18n();

const clicked = ref(false);
const code = ref("");
const email = ref("");
const isLogin = ref(false);
const loginForm = ref(null);
const phone = ref("");
const registrationCompleted = ref(false);
const showSubStep = ref(false);

const stepFiveForm = ref({
  daily_price_2h: null,
  daily_price_4h: null,
  daily_price_6h: null,
  daily_price_8h: null,
  services_types_ids: [],
});

const stepFourForm = ref({
  document_back: null,
  document_front: null,
  selfie: null,
});

const stepSixForm = ref({
  account_check_digit: "",
  account_number: "",
  account_type: "checking",
  bank: "",
  branch_check_digit: "",
  branch_number: "",
  pix_key: "",
  working_days: {},
});

const stepThreeForm = ref({
  address: "",
  address_type: "home",
  birth_date: "",
  city: "",
  complement: "",
  document: "",
  email: "",
  instructions: "",
  name: "",
  nickname: "Principal",
  no_complement: false,
  phone: "",
  rg: "",
  state: "",
  zip_code: "",
});

const steps = ref(1);

const submitting = ref(false);

const actionLabel = computed(() => {
  if (steps.value === 1) return t("provider.login.steps.step_1.action");
  if (steps.value === 2) return t("provider.login.steps.step_2.action");
  if (steps.value === 6) return t("provider.login.steps.step_6.action");

  return t("provider.login.steps.step_3.action");
});

const goBack = () => {
  if (steps.value === 4) {
    steps.value = 3;
  } else if (steps.value === 5) {
    steps.value = 4;
  } else if (steps.value === 6) {
    steps.value = 5;
  }
};

const hasWorkingDaySelected = () => mapWorkingDays().length > 0;

const mapWorkingDays = () => {
  const mapped = [];

  const workingDays = stepSixForm.value.working_days || {};

  Object.entries(workingDays).forEach(([dayKey, periods]) => {
    if (periods?.morning) {
      mapped.push({ day: Number(dayKey), period: "morning" });
    }

    if (periods?.afternoon) {
      mapped.push({ day: Number(dayKey), period: "afternoon" });
    }
  });

  return mapped;
};

const onSubmit = async () => {
  if (registrationCompleted.value) return;
  if (showSubStep.value) return;

  const isValid = await loginForm.value.validate();

  if (!isValid) return;

  submitting.value = true;

  try {
    switch (steps.value) {
      case 1: {
        const response = await sendValidationCode();

        isLogin.value = response?.data?.payload?.isLogin === true;

        break;
      }

      case 2:
        await validateCodeInput();

        break;

      case 3: {
        if (await validateCurrentStep()) {
          steps.value = 4;
        }

        break;
      }

      case 4: {
        if (await validateCurrentStep()) {
          steps.value = 5;
        }

        break;
      }

      case 5: {
        if (await validateCurrentStep()) {
          steps.value = 6;
        }

        break;
      }

      case 6: {
        if (await validateCurrentStep()) {
          await registerUserAndProvider();
        }

        break;
      }

      default:
        break;
    }
  } catch (error) {
    console.error(error);

    const msg =
      error?.response?.data?.message ??
      error?.message ??
      "Erro ao concluir cadastro. Tente novamente.";

    $q.notify({ message: msg, type: "negative" });
  } finally {
    submitting.value = false;
  }
};

const registerUserAndProvider = async () => {
  const workingDays = mapWorkingDays();

  const form = new FormData();

  const hasValue = (val) =>
    val !== null && val !== undefined && String(val).trim() !== "";

  const append = (key, val) => {
    if (val === null || val === undefined || val === "") return;

    if (typeof val === "boolean") {
      form.append(key, val ? "1" : "0");
    } else {
      form.append(key, val);
    }
  };

  const appendIfFilled = (key, val) => {
    if (!hasValue(val)) return;

    form.append(key, val);
  };

  append("name", stepThreeForm.value.name);
  append("email", stepThreeForm.value.email || email.value);
  append("phone", stepThreeForm.value.phone || phone.value);
  append("code", code.value);
  append("rg", stepThreeForm.value.rg);
  append("document", stepThreeForm.value.document);
  append("birth_date", toISODate(stepThreeForm.value.birth_date));
  append("zip_code", stepThreeForm.value.zip_code);
  append("address", stepThreeForm.value.address);
  append("has_complement", !stepThreeForm.value.no_complement);

  append(
    "complement",
    stepThreeForm.value.no_complement ? null : stepThreeForm.value.complement,
  );

  append("nickname", stepThreeForm.value.nickname);
  append("instructions", stepThreeForm.value.instructions);
  append("city", stepThreeForm.value.city);
  append("state", stepThreeForm.value.state);
  append("address_type", stepThreeForm.value.address_type);

  append("daily_price_8h", Number(stepFiveForm.value.daily_price_8h));
  append("daily_price_6h", Number(stepFiveForm.value.daily_price_6h));
  append("daily_price_4h", Number(stepFiveForm.value.daily_price_4h));
  append("daily_price_2h", Number(stepFiveForm.value.daily_price_2h));

  (stepFiveForm.value.services_types_ids ?? []).forEach((id) => {
    form.append("services_types_ids[]", id);
  });

  workingDays.forEach((workingDay, index) => {
    form.append(`working_days[${index}][day]`, workingDay.day);
    form.append(`working_days[${index}][period]`, workingDay.period);
  });

  form.append("selfie", stepFourForm.value.selfie);
  form.append("document_front", stepFourForm.value.document_front);
  form.append("document_back", stepFourForm.value.document_back);

  append("recipient_name", stepThreeForm.value.name);
  append("recipient_email", stepThreeForm.value.email || email.value);
  append("recipient_document", stepThreeForm.value.document);
  append("recipient_type", "individual");

  const hasBankAccountData = [
    stepSixForm.value.bank,
    stepSixForm.value.branch_number,
    stepSixForm.value.account_number,
    stepSixForm.value.account_check_digit,
  ].every(hasValue);

  if (hasBankAccountData) {
    append("recipient_payment_mode", "bank_transfer");
    append(
      "recipient_default_bank_account[type]",
      stepSixForm.value.account_type,
    );

    append("recipient_default_bank_account[bank]", stepSixForm.value.bank);

    append(
      "recipient_default_bank_account[branch_number]",
      stepSixForm.value.branch_number,
    );

    appendIfFilled(
      "recipient_default_bank_account[branch_check_digit]",
      stepSixForm.value.branch_check_digit,
    );

    append(
      "recipient_default_bank_account[account_number]",
      stepSixForm.value.account_number,
    );

    append(
      "recipient_default_bank_account[account_check_digit]",
      stepSixForm.value.account_check_digit,
    );

    appendIfFilled(
      "recipient_default_bank_account[pix_key]",
      stepSixForm.value.pix_key,
    );

    append(
      "recipient_default_bank_account[holder_name]",
      stepThreeForm.value.name,
    );

    append(
      "recipient_default_bank_account[holder_document]",
      stepThreeForm.value.document,
    );

    append("recipient_default_bank_account[holder_type]", "individual");
  }

  const response = await createUserAndProvider(form);

  if (response.status >= 200 && response.status < 300) {
    registrationCompleted.value = true;
  }
};

const sendValidationCode = async () => {
  const response = await sendCode(email.value, phone.value);

  if (response.status === 201) {
    steps.value = 2;
  }

  return response;
};

const toISODate = (value) => {
  const matches = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(value || "");

  if (!matches) return null;

  return `${matches[3]}-${matches[2]}-${matches[1]}`;
};

const validateCodeInput = async () => {
  const response = await validateCode(
    email.value,
    phone.value,
    code.value,
    isLogin.value,
  );

  if (response.status === 200) {
    if (isLogin.value === true) {
      await setAuthDataFromPayload(response.data.payload);

      router.push({ name: "DashboardPage" });

      return;
    }

    stepThreeForm.value.email = email.value;
    stepThreeForm.value.phone = phone.value;
    steps.value = 3;
  }
};

const validateCurrentStep = async () => {
  const isValid = await loginForm.value?.validate();

  if (!isValid) return false;

  if (steps.value === 4) {
    const hasDocumentBack = !!stepFourForm.value.document_back;
    const hasDocumentFront = !!stepFourForm.value.document_front;
    const hasSelfie = !!stepFourForm.value.selfie;

    if (!hasSelfie || !hasDocumentFront || !hasDocumentBack) {
      $q.notify({
        message: t("provider.login.steps.step_4.upload_all_photos"),
        type: "negative",
      });

      return false;
    }
  }

  if (steps.value === 6 && !hasWorkingDaySelected()) {
    $q.notify({
      message: t("provider.login.steps.step_6.select_at_least_one"),
      type: "negative",
    });

    return false;
  }

  return true;
};

onMounted(() => {
  setTimeout(() => {
    clicked.value = true;
  }, 1500);
});
</script>
<style lang="scss" scoped>
.fade-slide-enter-active,
.fade-slide-leave-active {
  transition:
    opacity 0.35s ease,
    transform 0.35s ease;
}
.fade-slide-enter-from {
  opacity: 0;
  transform: translateY(6px);
}
.fade-slide-leave-to {
  opacity: 0;
  transform: translateY(-6px);
}

.login-page {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  background: var(--q-surface-dark);
}

.splash-screen {
  position: relative;
  width: 100vw;
  min-height: 100vh;
  overflow: hidden;
  cursor: pointer;

  .splash-layer {
    position: absolute;

    &--bg {
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    &--photo {
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      opacity: 0.15;
      mix-blend-mode: multiply;
    }

    &--logo {
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 180px;
      z-index: 1;
    }
  }
}

.flow-screen {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 500px;
  min-height: 100vh;
  padding: 16px 20px;
  background: var(--q-surface-dark);
}

.flow-header {
  min-height: 36px;
  padding-left: max(4px, env(safe-area-inset-left));
}

.flow-back-btn {
  margin-left: -4px;
}

.flow-logo {
  display: flex;
  justify-content: center;
  padding: 12px 0 20px;
}

.flow-form {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.flow-content {
  flex: 1;
  overflow-y: auto;

  &--centered {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.flow-footer {
  padding: 20px 0 calc(12px + env(safe-area-inset-bottom));
}

.registration-complete {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px 8px 80px;
  text-align: center;

  &__title {
    font-size: 18px;
    line-height: 1.25;
    margin-bottom: 10px;
  }

  &__message {
    max-width: 320px;
    line-height: 1.45;
  }
}
</style>
