<script setup lang="ts">
import { useMutation, useQuery } from '@vue/apollo-composable';
import {
  DeleteMyMessengerConnectionDocument,
  MeDocument,
  MyMessengerConnectionsDocument,
} from '~/composables/graphql/generated';
import {
  messengerConnectionAvatarSrc,
  messengerConnectionHandle,
  messengerConnectionInitials,
  messengerConnectionName,
} from '~/composables/useMessengerConnectionPresentation';
import { useMessengerStart } from '~/composables/useMessengerStart';

type MessengerChannel = 'TELEGRAM' | 'MAX';

type MessengerItem = {
  id: string;
  type: MessengerChannel;
  isActive: boolean;
  channelId: string;
  displayName?: string | null;
  username?: string | null;
  avatarAvailable?: boolean | null;
};

type MessengerOption = {
  channel: MessengerChannel;
  label: string;
  buttonClass: string;
  iconClass: string;
  unavailableText: string;
};

const config = useRuntimeConfig();
const feedback = ref('');
const meQuery = useQuery(MeDocument);
const connectionsQuery = useQuery(MyMessengerConnectionsDocument);
const deleteConnectionMutation = useMutation(DeleteMyMessengerConnectionDocument);
const { openMessengerBot, pendingChannel } = useMessengerStart();

const telegramConnection = computed(() =>
  connectionsQuery.result.value?.myMessengerConnections?.find(
    (item: MessengerItem) => item.type === 'TELEGRAM' && item.isActive,
  ) ?? null,
);

const maxConnection = computed(() =>
  connectionsQuery.result.value?.myMessengerConnections?.find(
    (item: MessengerItem) => item.type === 'MAX' && item.isActive,
  ) ?? null,
);

const messengerOptions: MessengerOption[] = [
  {
    channel: 'TELEGRAM',
    label: 'Telegram',
    buttonClass: 'bg-[#1a9c63] text-white hover:bg-[#148553]',
    iconClass: 'bg-[#123824] text-white',
    unavailableText: 'Telegram пока не настроен в окружении фронта.',
  },
  {
    channel: 'MAX',
    label: 'MAX',
    buttonClass: 'bg-[#2b7fff] text-white hover:bg-[#1d6df1]',
    iconClass: 'bg-[#2b7fff] text-white',
    unavailableText: 'MAX пока не настроен в окружении фронта.',
  },
];

function buildBotConnectUrl(baseUrl: string) {
  const accountEmail = meQuery.result.value?.me?.email?.trim().toLowerCase();
  if (!accountEmail || !baseUrl) {
    return '';
  }

  return baseUrl;
}

const telegramConnectUrl = computed(() => buildBotConnectUrl(config.public.telegramBotUrl || ''));
const maxConnectUrl = computed(() => buildBotConnectUrl(config.public.maxBotUrl || ''));

function connectUrl(channel: MessengerChannel) {
  return channel === 'TELEGRAM' ? telegramConnectUrl.value : maxConnectUrl.value;
}

function connectionFor(channel: MessengerChannel) {
  return channel === 'TELEGRAM' ? telegramConnection.value : maxConnection.value;
}

const activeConnections = computed(() => messengerOptions
  .map((option) => ({
    option,
    connection: connectionFor(option.channel),
  }))
  .filter((item) => Boolean(item.connection)));

const availableOptions = computed(() => messengerOptions
  .filter((option) => !connectionFor(option.channel)));

async function connectMessenger(channel: MessengerChannel) {
  feedback.value = '';
  const baseUrl = connectUrl(channel);

  if (!baseUrl) {
    feedback.value = channel === 'MAX'
      ? 'MAX не откроется, пока не задан NUXT_PUBLIC_MAX_BOT_URL.'
      : 'Telegram не откроется, пока не задан NUXT_PUBLIC_TELEGRAM_BOT_URL.';
    return;
  }

  await openMessengerBot({
    channel,
    baseUrl,
    redirectPath: `/profile/notifications/success?connected=${channel.toLowerCase()}`,
  });
}

async function removeConnection(connectionId: string) {
  feedback.value = '';
  const result = await deleteConnectionMutation.mutate({
    connectionId,
  });

  if (!result?.data?.deleteMyMessengerConnection) {
    feedback.value = 'Не удалось отключить аккаунт. Попробуйте еще раз.';
    return;
  }

  await connectionsQuery.refetch();
}
</script>

<template>
  <section class="space-y-6">
    <NuxtLink to="/profile" class="link link-hover text-sm">← Назад в профиль</NuxtLink>

    <div class="space-y-2">
      <h1 class="text-3xl font-extrabold text-[#0f2f20]">Уведомления</h1>
      <p class="text-sm leading-6 text-[#466653]">
        Подключите мессенджер, чтобы получать уведомления по заказам.
      </p>
    </div>

    <div
      v-if="feedback"
      class="rounded-[24px] border px-4 py-3 text-sm font-medium"
      :class="feedback.includes('Не удалось') || feedback.includes('не откроется')
        ? 'border-[#f1d1c7] bg-[#fff3ef] text-[#9d4426]'
        : 'border-[#cbe9d6] bg-[#f1fbf5] text-[#1c6b45]'"
    >
      {{ feedback }}
    </div>

    <div class="rounded-[32px] bg-[#edf3ee] p-6 md:p-8">
      <div
        v-if="activeConnections.length > 0"
        class="space-y-4"
      >
        <article
          v-for="{ option, connection } in activeConnections"
          :key="connection!.id"
          class="rounded-[28px] bg-white px-5 py-4 shadow-[0_18px_38px_rgba(18,56,36,0.08)]"
        >
          <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
            <div class="flex min-w-0 items-center gap-4">
              <div v-if="messengerConnectionAvatarSrc(connection)" class="avatar">
                <div class="h-14 w-14 rounded-[20px]">
                  <img :src="messengerConnectionAvatarSrc(connection)" :alt="messengerConnectionName(connection)">
                </div>
              </div>
              <div
                v-else
                class="flex h-14 w-14 items-center justify-center rounded-[20px] text-sm font-black"
                :class="option.iconClass"
              >
                {{ messengerConnectionInitials(connection, option.channel === 'TELEGRAM' ? 'TG' : 'MX') }}
              </div>

              <div class="min-w-0">
                <p class="text-[11px] font-semibold uppercase tracking-[0.18em] text-[#6a8a76]">{{ option.label }}</p>
                <p class="truncate text-lg font-bold text-[#123824]">{{ messengerConnectionName(connection) }}</p>
                <p class="truncate text-sm text-[#557562]">{{ messengerConnectionHandle(connection) || connection.channelId }}</p>
              </div>
            </div>

            <button
              class="btn rounded-full border border-[#e5cfc7] bg-[#fff5f1] px-5 text-[#a64d2d] hover:border-[#deb5a8] hover:bg-[#ffe8e0]"
              :disabled="deleteConnectionMutation.loading.value"
              @click="removeConnection(connection!.id)"
            >
              {{ deleteConnectionMutation.loading.value ? 'Отключаем...' : 'Отключить' }}
            </button>
          </div>
        </article>
      </div>

      <p
        v-else
        class="text-sm leading-6 text-[#557562]"
      >
        Пока ничего не подключено.
      </p>

      <div
        v-if="availableOptions.length > 0"
        class="mt-6 grid gap-4 md:grid-cols-2"
      >
        <button
          v-for="option in availableOptions"
          :key="option.channel"
          class="flex min-h-[104px] flex-col items-start justify-between rounded-[28px] border-0 px-5 py-5 text-left shadow-[0_18px_38px_rgba(18,56,36,0.08)] transition"
          :class="[option.buttonClass, { 'opacity-60': !connectUrl(option.channel) }]"
          :disabled="pendingChannel === option.channel || !connectUrl(option.channel)"
          @click="connectMessenger(option.channel)"
        >
          <div class="inline-flex h-11 w-11 items-center justify-center rounded-2xl bg-white/18 text-sm font-black text-white">
            {{ option.channel === 'TELEGRAM' ? 'TG' : 'MX' }}
          </div>
          <p class="text-sm font-semibold text-white">
            {{ pendingChannel === option.channel ? `Открываем ${option.label}...` : `Подключить ${option.label}` }}
          </p>
        </button>
      </div>

      <div class="mt-4 space-y-2">
        <p
          v-for="option in availableOptions.filter((item) => !connectUrl(item.channel))"
          :key="`${option.channel}-hint`"
          class="text-sm text-[#8b5a49]"
        >
          {{ option.unavailableText }}
        </p>
      </div>
    </div>
  </section>
</template>
