<script setup lang="ts">
import { useMutation } from '@vue/apollo-composable';
import {
  ConsumeLoginTokenDocument,
  RequestLoginCodeDocument,
  VerifyLoginCodeDocument,
} from '~/composables/graphql/generated';

type LoginChannel = 'EMAIL' | 'TELEGRAM' | 'MAX';

const config = useRuntimeConfig();
const route = useRoute();
const authCookieName = config.public.authCookieName || 'fregat_auth_token';
const authCookie = useCookie<string | null>(authCookieName, {
  sameSite: 'lax',
  maxAge: 60 * 60 * 24 * 30,
});

const step = ref<'request' | 'verify'>('request');
const channel = ref<LoginChannel>('EMAIL');
const destination = ref('');
const challengeToken = ref('');
const maskedDestination = ref('');
const expiresAt = ref('');
const code = ref('');
const feedback = ref('');
const feedbackTone = ref<'success' | 'error'>('success');
const userIdForBot = ref('');

const requestCodeMutation = useMutation(RequestLoginCodeDocument);
const verifyCodeMutation = useMutation(VerifyLoginCodeDocument);
const consumeLoginTokenMutation = useMutation(ConsumeLoginTokenDocument);

const channelHint = computed(() => {
  return 'Email адрес';
});

const telegramBotUrl = computed(() => config.public.telegramBotUrl || '');
const maxBotUrl = computed(() => config.public.maxBotUrl || '');
const selectedBotUrl = computed(() =>
  channel.value === 'TELEGRAM'
    ? telegramBotUrl.value
    : maxBotUrl.value,
);
const startCommand = computed(() =>
  userIdForBot.value.trim() ? `/start ${userIdForBot.value.trim()}` : '/start <ваш_user_id>',
);

async function finalizeSession(accessToken: string) {
  authCookie.value = accessToken;
  await navigateTo('/products');
}

async function requestCode() {
  if (channel.value !== 'EMAIL') {
    feedback.value = 'Кодовый вход доступен только для Email.';
    feedbackTone.value = 'error';
    return;
  }

  feedback.value = '';
  const result = await requestCodeMutation.mutate({
    input: {
      channel: channel.value,
      destination: destination.value.trim(),
    },
  });

  const payload = result?.data?.requestLoginCode;
  if (!payload) {
    feedback.value = 'Не получилось отправить код.';
    feedbackTone.value = 'error';
    return;
  }

  challengeToken.value = payload.challengeToken;
  maskedDestination.value = payload.destination;
  expiresAt.value = new Date(payload.expiresAt).toLocaleString();
  feedback.value = `Код отправлен на ${payload.destination}. Тестовый код сейчас: 123456`;
  feedbackTone.value = 'success';
  step.value = 'verify';
}

async function verifyCode() {
  feedback.value = '';
  const result = await verifyCodeMutation.mutate({
    input: {
      challengeToken: challengeToken.value,
      code: code.value.trim(),
    },
  });

  const payload = result?.data?.verifyLoginCode;
  if (!payload) {
    feedback.value = 'Не получилось выполнить вход.';
    feedbackTone.value = 'error';
    return;
  }

  await finalizeSession(payload.accessToken);
}

async function consumeLoginToken(loginToken: string) {
  feedback.value = '';
  const result = await consumeLoginTokenMutation.mutate({
    token: loginToken,
  });
  const payload = result?.data?.consumeLoginToken;
  if (!payload) {
    feedback.value = 'Временный токен входа недействителен.';
    feedbackTone.value = 'error';
    return;
  }
  await finalizeSession(payload.accessToken);
}

function copyStartCommand() {
  navigator.clipboard.writeText(startCommand.value);
  feedback.value = `Команда скопирована: ${startCommand.value}`;
  feedbackTone.value = 'success';
}

watch(channel, () => {
  feedback.value = '';
  if (channel.value !== 'EMAIL') {
    step.value = 'request';
  }
});

onMounted(async () => {
  const loginToken = typeof route.query.login_token === 'string' ? route.query.login_token : '';
  if (loginToken) {
    await consumeLoginToken(loginToken);
  }
});
</script>

<template>
  <section class="mx-auto flex min-h-[calc(100vh-4rem)] w-full max-w-3xl items-center py-8">
    <div class="surface-card w-full rounded-[34px] p-5 md:p-8">
      <div class="mb-5 text-center">
        <h1 class="text-3xl font-extrabold text-[#0f2f20]">Вход в личный кабинет</h1>
        <p class="mt-1 text-sm text-[#28543f]/80">
          Email вход по коду. Telegram/Max вход через бота и временный токен.
        </p>
      </div>

      <div class="mx-auto mb-5 flex w-full max-w-xl flex-wrap items-center justify-center gap-2">
        <button
          class="glass-capsule rounded-full px-4 py-2 text-sm font-semibold text-[#123824] transition hover:scale-[1.01]"
          :class="{ 'bg-[#139957] text-white': channel === 'EMAIL' }"
          @click="channel = 'EMAIL'"
        >
          Email
        </button>
        <button
          class="glass-capsule rounded-full px-4 py-2 text-sm font-semibold text-[#123824] transition hover:scale-[1.01]"
          :class="{ 'bg-[#139957] text-white': channel === 'TELEGRAM' }"
          @click="channel = 'TELEGRAM'"
        >
          Telegram
        </button>
        <button
          class="glass-capsule rounded-full px-4 py-2 text-sm font-semibold text-[#123824] transition hover:scale-[1.01]"
          :class="{ 'bg-[#139957] text-white': channel === 'MAX' }"
          @click="channel = 'MAX'"
        >
          Max
        </button>
      </div>

      <div v-if="channel === 'EMAIL' && step === 'request'" class="space-y-3">
        <label class="form-control">
          <span class="label-text font-semibold text-[#194631]">{{ channelHint }}</span>
          <input
            v-model="destination"
            type="text"
            class="input input-bordered border-[#d0e8d8] bg-white/80"
            :placeholder="channelHint"
          >
        </label>

        <button
          class="btn w-full border-0 bg-[#139957] text-white hover:bg-[#0d854a]"
          :disabled="requestCodeMutation.loading.value"
          @click="requestCode"
        >
          {{ requestCodeMutation.loading.value ? 'Отправляем…' : 'Получить код' }}
        </button>
      </div>

      <div v-else-if="channel === 'EMAIL'" class="space-y-3">
        <div class="rounded-xl border border-[#d6ebde] bg-white/75 p-3 text-sm text-[#214735]">
          Код отправлен на <span class="font-bold">{{ maskedDestination }}</span>.
          Действителен до: <span class="font-bold">{{ expiresAt }}</span>.
        </div>

        <label class="form-control">
          <span class="label-text font-semibold text-[#194631]">Код подтверждения</span>
          <input
            v-model="code"
            type="text"
            maxlength="6"
            class="input input-bordered border-[#d0e8d8] bg-white/80"
            placeholder="123456"
          >
        </label>

        <button
          class="btn w-full border-0 bg-[#139957] text-white hover:bg-[#0d854a]"
          :disabled="verifyCodeMutation.loading.value"
          @click="verifyCode"
        >
          {{ verifyCodeMutation.loading.value ? 'Проверяем…' : 'Войти' }}
        </button>

        <button class="btn btn-ghost w-full" @click="step = 'request'">
          Выбрать другой канал
        </button>
      </div>

      <div v-else class="space-y-4">
        <div class="rounded-xl border border-[#d6ebde] bg-white/75 p-3 text-sm text-[#214735]">
          Откройте {{ channel === 'TELEGRAM' ? 'Telegram' : 'Max' }}-бота, отправьте команду
          <span class="font-bold">{{ startCommand }}</span>, затем передайте боту свой <code>user_id</code>.
          Бот пришлёт кнопку входа в кабинет с временным токеном.
        </div>

        <label class="form-control">
          <span class="label-text font-semibold text-[#194631]">Ваш user_id (для команды /start)</span>
          <input
            v-model="userIdForBot"
            type="text"
            class="input input-bordered border-[#d0e8d8] bg-white/80"
            placeholder="например: cm5abc123xyz"
          >
        </label>

        <div class="grid gap-2 sm:grid-cols-2">
          <button class="btn btn-outline border-[#139957] text-[#0d854a]" @click="copyStartCommand">
            Скопировать команду
          </button>
          <a
            :href="selectedBotUrl || undefined"
            target="_blank"
            rel="noopener noreferrer"
            class="btn border-0 bg-[#139957] text-white hover:bg-[#0d854a]"
            :class="{ 'btn-disabled pointer-events-none': !selectedBotUrl }"
          >
            Открыть бота
          </a>
        </div>

        <p v-if="!selectedBotUrl" class="text-xs text-[#b42318]">
          Ссылка на {{ channel === 'TELEGRAM' ? 'Telegram' : 'Max' }}-бота не настроена в env.
        </p>
      </div>

      <div
        v-if="feedback"
        class="alert mt-4"
        :class="feedbackTone === 'success' ? 'alert-success' : 'alert-error'"
      >
        {{ feedback }}
      </div>
    </div>
  </section>
</template>
