<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">
    <UiBackHeader
      to="/profile"
      back-label="Назад в профиль"
      title="Уведомления"
      subtitle="Подключите мессенджер, чтобы получать уведомления по заказам."
    />

    <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
      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="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="space-y-4"
    >
      <button
        v-for="option in availableOptions"
        :key="option.channel"
        class="flex w-full items-center 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="flex items-center gap-4">
          <div
            class="inline-flex h-11 min-w-11 items-center justify-center rounded-2xl bg-white text-sm font-black"
            :class="option.channel === 'TELEGRAM' ? 'text-[#1a9c63]' : 'text-[#2b7fff]'"
          >
            {{ option.channel === 'TELEGRAM' ? 'TG' : 'MAX' }}
          </div>

          <p class="text-base font-semibold text-white">
            {{ pendingChannel === option.channel ? `Открываем ${option.label}...` : `Подключить ${option.label}` }}
          </p>
        </div>
      </button>

      <div class="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>
