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

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

        <q-form
          ref="loginForm"
          class="flow-form"
          autocorrect="off"
          autocapitalize="off"
          autocomplete="off"
          spellcheck="false"
          @submit="onSubmit"
        >
          <div class="flow-content" :class="{ 'flow-content--centered': steps <= 2 && !showSubStep }">
            <LoginStepOnePanel v-if="steps === 1" v-model:email="email" v-model:phone="phone" />
            <LoginStepTwoPanel v-else-if="steps === 2" v-model:code="code" />
            <LoginStepThreePanel v-else-if="steps === 3" v-model="stepThreeForm" />
            <LoginStepFourPanel
              v-else-if="steps === 4"
              v-model="stepFourForm"
              @update:show-sub-step="showSubStep = $event"
            />
            <LoginStepFivePanel v-else-if="steps === 5" v-model="stepFiveForm" />
            <LoginStepSixPanel v-else-if="steps === 6" v-model="stepSixForm" />

            <div v-else-if="steps === 7" class="column items-center justify-center q-gutter-md text-center">
              <q-icon name="mdi-clock-outline" size="64px" color="warning" />
              <div class="text-h6 text-text">{{ $t('provider.login.pending_approval.title') }}</div>
              <div class="text-body2 text-grey-5">{{ $t('provider.login.pending_approval.description') }}</div>
            </div>
          </div>

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

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

import BackgroundLogin from 'src/assets/background-login.svg';
import FotoDiarista from 'src/assets/foto_diarista_login.svg';
import LogoLogin from 'src/assets/logo_diaria_login.svg';
import LogoDiariaCampos from 'src/assets/logo_diaria_campos_login.svg';

import LoginStepOnePanel from 'src/components/login/LoginStepOnePanel.vue';
import LoginStepTwoPanel from 'src/components/login/LoginStepTwoPanel.vue';
import LoginStepThreePanel from 'src/components/login/LoginStepThreePanel.vue';
import LoginStepFourPanel from 'src/components/login/LoginStepFourPanel.vue';
import LoginStepFivePanel from 'src/components/login/LoginStepFivePanel.vue';
import LoginStepSixPanel from 'src/components/login/LoginStepSixPanel.vue';

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

const clicked = ref(false);
const showSubStep = ref(false);
const steps = ref(1);
const submitting = ref(false);
const loginForm = ref(null);
const isLogin = ref(false);

const email = ref('');
const phone = ref('');
const code = ref('');

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

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

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

const stepSixForm = ref({
  working_days: {},
});

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 toISODate = (value) => {
  const matches = /^(\d{2})\/(\d{2})\/(\d{4})$/.exec(value || '');
  if (!matches) return null;

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

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 hasWorkingDaySelected = () => {
  return mapWorkingDays().length > 0;
};

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

  if (!isValid) {
    return false;
  }

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

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

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

  return true;
};

const sendValidationCode = async () => {
  const response = await sendCode(email.value, phone.value);
  if (response.status === 201) {
    steps.value = 2;
  }
  return response;
};

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 registerUserAndProvider = async () => {
  const workingDays = mapWorkingDays();
  const form = new FormData();

  const append = (key, val) => {
    if (val === null || val === undefined) return;
    if (typeof val === 'boolean') form.append(key, val ? '1' : '0');
    else 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((wd, i) => {
    form.append(`working_days[${i}][day]`, wd.day);
    form.append(`working_days[${i}][period]`, wd.period);
  });

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

  const response = await createUserAndProvider(form);
  if (response.status === 200) {
    steps.value = 7;
  }
};

const onSubmit = async () => {
  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);
  } finally {
    submitting.value = false;
  }
};
</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;
}

.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 12px;
}
</style>
