<script setup lang="ts">
import WizardPage from "@/components/onboarding/WizardPage.vue";
import { computed, ref, watch } from "vue";
import { type User, useUserStore } from "@/stores/user";
import PersonalAddress from "@/components/onboarding/PersonalAddress.vue";
import OrganisationAddress from "@/components/onboarding/OrganisationAddress.vue";
import { itPost } from "@/fetchHelpers";
import { useEntities } from "@/services/entities";
import { useRoute } from "vue-router";
import { useTranslation } from "i18next-vue";
import { getVVCourseName } from "./composables";
import DatatransCembraDeviceFingerprint from "@/components/onboarding/DatatransCembraDeviceFingerprint.vue";
import { getLocalSessionKey } from "@/statistics";
import log from "loglevel";
import { normalizeSwissPhoneNumber, validatePhoneNumber } from "@/utils/phone";
import {
  ORGANISATION_NO_COMPANY_ID,
  ORGANISATION_OTHER_BROKER_ID,
  ORGANISATION_OTHER_HEALTH_INSURANCE_ID,
  ORGANISATION_OTHER_PRIVATE_INSURANCE_ID,
} from "@/consts";

const props = defineProps({
  courseType: {
    type: String,
    required: true,
  },
});

const user = useUserStore();
const route = useRoute();
const { organisations, countries } = useEntities();

const userOrganisationName = computed(() => {
  if (!user.organisation) {
    return null;
  }

  // Those IDs do not represent a company
  if (
    [
      ORGANISATION_OTHER_BROKER_ID,
      ORGANISATION_OTHER_HEALTH_INSURANCE_ID,
      ORGANISATION_OTHER_PRIVATE_INSURANCE_ID,
      ORGANISATION_NO_COMPANY_ID,
    ].includes(user.organisation)
  ) {
    return null;
  }

  return organisations.value?.find((c) => c.id === user.organisation)?.name;
});

const paymentError = computed(() => {
  return "error" in route.query;
});

const address = ref({
  first_name: user.first_name,
  last_name: user.last_name,
  street: user.street,
  street_number: user.street_number,
  postal_code: user.postal_code,
  city: user.city,
  country_code: user.country?.country_code ?? "CH",

  payment_method: "credit_card",

  phone_number: user.phone_number,
  birth_date: user.birth_date,

  organisation_detail_name: user.organisation_detail_name,
  organisation_street: user.organisation_street,
  organisation_street_number: user.organisation_street_number,
  organisation_postal_code: user.organisation_postal_code,
  organisation_city: user.organisation_city,
  organisation_country_code: user.organisation_country?.country_code ?? "CH",
  invoice_address: user.invoice_address ?? "prv",
});

const withCompanyAddress = ref(user.invoice_address === "org");

const setWithCompanyAddress = (value: boolean) => {
  withCompanyAddress.value = value;
  address.value.invoice_address = value ? "org" : "prv";
};

watch(
  () => address.value.payment_method,
  (newValue) => {
    if (newValue === "cembra_byjuno") {
      setWithCompanyAddress(false);
    }
  }
);

type FormErrors = {
  personal: string[];
  company: string[];
};

const formErrors = ref<FormErrors>({
  personal: [],
  company: [],
});

const { t } = useTranslation();

function validateAddress() {
  formErrors.value.personal = [];
  formErrors.value.company = [];

  if (!address.value.first_name) {
    formErrors.value.personal.push(t("a.Vorname"));
  }

  if (!address.value.last_name) {
    formErrors.value.personal.push(t("a.Nachname"));
  }

  if (!address.value.street) {
    formErrors.value.personal.push(t("a.Strasse"));
  }

  if (!address.value.street_number) {
    formErrors.value.personal.push(t("a.Hausnummmer"));
  }

  if (!address.value.postal_code) {
    formErrors.value.personal.push(t("a.PLZ"));
  }

  if (!address.value.city) {
    formErrors.value.personal.push(t("a.Ort"));
  }

  if (!address.value.country_code) {
    formErrors.value.personal.push(t("a.Land"));
  }

  if (address.value.phone_number) {
    const normalizedPhoneNumber = normalizeSwissPhoneNumber(address.value.phone_number);
    log.debug("normalizedPhoneNumber", normalizedPhoneNumber);
    if (!validatePhoneNumber(normalizedPhoneNumber)) {
      formErrors.value.personal.push(t("a.Telefonnummer hat das falsche Format"));
    }
  }

  if (address.value.payment_method === "cembra_byjuno") {
    if (!address.value.phone_number) {
      formErrors.value.personal.push(t("a.Telefonnummer"));
    }

    if (!address.value.birth_date) {
      formErrors.value.personal.push(t("a.Geburtsdatum"));
    }
  }

  if (withCompanyAddress.value) {
    if (!address.value.organisation_detail_name) {
      formErrors.value.company.push(t("a.Name"));
    }

    if (!address.value.organisation_street) {
      formErrors.value.company.push(t("a.Strasse"));
    }

    if (!address.value.organisation_street_number) {
      formErrors.value.company.push(t("a.Hausnummmer"));
    }

    if (!address.value.organisation_postal_code) {
      formErrors.value.company.push(t("a.PLZ"));
    }

    if (!address.value.organisation_city) {
      formErrors.value.company.push(t("a.Ort"));
    }

    if (!address.value.organisation_country_code) {
      formErrors.value.company.push(t("a.Land"));
    }
  }
}

async function saveAddress() {
  const { country_code, organisation_country_code, phone_number, ...profileData } =
    address.value;
  const typedProfileData: Partial<User> = { ...profileData };

  typedProfileData.country = countries.value.find(
    (c) => c.country_code === country_code
  );
  typedProfileData.organisation_country = countries.value.find(
    (c) => c.country_code === organisation_country_code
  );

  if (phone_number) {
    typedProfileData.phone_number = normalizeSwissPhoneNumber(phone_number);
  }

  await user.updateUserProfile(typedProfileData);
}

const executePayment = async () => {
  validateAddress();
  if (formErrors.value.personal.length > 0 || formErrors.value.company.length > 0) {
    return;
  }

  await saveAddress();

  // Where the payment page will redirect to after the payment is done:
  // The reason why this is here is convenience: We could also do this in the backend
  // then we'd need to configure this for all environments (including Caprover).
  // /server/transactions/redirect?... will just redirect to the frontend to the right page
  // anyway, so it seems fine to do it here.
  const fullHost = `${window.location.protocol}//${window.location.host}`;

  if (address.value.phone_number) {
    address.value.phone_number = normalizeSwissPhoneNumber(address.value.phone_number);
  }

  const addressData = Object.assign({}, address.value);
  // @ts-ignore
  delete addressData.payment_method;

  itPost("/api/shop/vv/checkout/", {
    redirect_url: fullHost,
    address: addressData,
    product: props.courseType,
    with_cembra_byjuno_invoice: address.value.payment_method === "cembra_byjuno",
    device_fingerprint_session_key: getLocalSessionKey(),
  }).then((res: any) => {
    console.log("Going to next page", res.next_step_url);
    window.location.href = res.next_step_url;
  });
};
</script>

<template>
  <WizardPage :step="2">
    <template #content>
      <DatatransCembraDeviceFingerprint
        v-if="address.payment_method === 'cembra_byjuno'"
      />
      <h2 class="my-10" data-cy="account-checkout-title">
        {{ $t("a.Lehrgang kaufen") }}
      </h2>
      <p class="mb-4">
        <i18next
          :translation="$t('a.Der Preis für den Lehrgang {course} beträgt {price}.')"
        >
          <template #course>
            <b>«{{ getVVCourseName(props.courseType, $t) }}»</b>
          </template>
          <template #price>
            <b class="whitespace-nowrap">300 CHF</b>
          </template>
        </i18next>
        {{
          $t("a.Mit dem Kauf erhältst du Zugang auf den gesamten Kurs (inkl. Prüfung).")
        }}
      </p>

      <p v-if="paymentError" class="text-bold mt-12 text-lg text-red-700">
        {{
          $t(
            "a.Fehler bei der Zahlung. Bitte versuche es erneut oder wähle eine andere Zahlungsmethode."
          )
        }}
      </p>

      <h3 class="mb-4 mt-10">{{ $t("a.Adresse") }}</h3>
      <p class="mb-2">
        {{
          $t(
            "a.Um die Zahlung vornehmen zu können, benötigen wir deine Privatadresse. Optional kannst du die Rechnungsadresse deiner Gesellschaft hinzufügen."
          )
        }}
      </p>
      <p>
        {{
          $t(
            "Wichtig: wird die Rechnung von deinem Arbeitgeber bezahlt, dann kannst du zusätzlich die Rechnungsadresse deines Arbeitsgebers erfassen."
          )
        }}
      </p>
      <PersonalAddress v-model="address" />

      <p v-if="formErrors.personal.length" class="mb-10 text-red-700">
        {{ $t("a.Bitte folgende Felder ausfüllen") }}:
        {{ formErrors.personal.join(", ") }}
      </p>

      <section>
        <div class="mt-4">
          <button
            v-if="!withCompanyAddress"
            class="underline"
            data-cy="add-company-address"
            @click="setWithCompanyAddress(true)"
          >
            <template v-if="userOrganisationName">
              {{
                $t("a.Rechnungsadresse von {organisation} hinzufügen", {
                  organisation: userOrganisationName,
                })
              }}
            </template>
            <template v-else>{{ $t("a.Rechnungsadresse hinzufügen") }}</template>
          </button>
        </div>

        <transition
          enter-active-class="transition ease-out duration-100"
          enter-from-class="transform opacity-0 scale-y-95"
          enter-to-class="transform opacity-100 scale-y-100"
          leave-active-class="transition ease-in duration-75"
          leave-from-class="transform opacity-100 scale-y-100"
          leave-to-class="transform opacity-0 scale-y-95"
        >
          <div v-if="withCompanyAddress">
            <div class="flex items-center justify-between">
              <h3 v-if="userOrganisationName">
                {{
                  $t("a.Rechnungsadresse von {organisation}", {
                    organisation: userOrganisationName,
                  })
                }}
              </h3>
              <h3 v-else>{{ $t("a.Rechnungsadresse") }}</h3>
              <button class="underline" @click="setWithCompanyAddress(false)">
                {{ $t("a.Entfernen") }}
              </button>
            </div>
            <OrganisationAddress v-model="address" />
            <p v-if="formErrors.company.length" class="text-red-700">
              {{ $t("a.Bitte folgende Felder ausfüllen") }}:
              {{ formErrors.company.join(", ") }}
            </p>
          </div>
        </transition>
      </section>
    </template>

    <template #footer>
      <router-link
        :to="{ name: 'accountProfile' }"
        class="btn-secondary flex items-center"
      >
        <it-icon-arrow-left class="it-icon mr-2 h-6 w-6" />
        {{ $t("general.back") }}
      </router-link>
      <button
        class="btn-blue flex items-center"
        data-cy="continue-pay"
        @click="executePayment"
      >
        <template v-if="address.payment_method === 'cembra_byjuno'">
          {{ $t("a.Mit Rechnung bezahlen") }}
        </template>
        <template v-else>
          {{ $t("a.Mit Kreditkarte bezahlen") }}
        </template>
        <it-icon-arrow-right class="it-icon ml-2 h-6 w-6" />
      </button>
    </template>
  </WizardPage>
</template>
