<script setup lang="ts">
import { useMutation, useQuery } from '@vue/apollo-composable';
import {
  MyCounterpartyProfileDocument,
  UpsertMyCounterpartyProfileDocument,
} from '~/composables/graphql/generated';
import { isCounterpartyProfileComplete } from '~/composables/useCounterpartyProfile';

type PartySuggestion = {
  value: string;
  unrestricted_value?: string;
  data?: {
    inn?: string;
    kpp?: string;
    ogrn?: string;
    address?: { value?: string };
    management?: {
      name?: string;
      post?: string;
    };
  };
};

type BankSuggestion = {
  value: string;
  unrestricted_value?: string;
  data?: {
    bic?: string;
    correspondent_account?: string;
  };
};

const counterpartyForm = reactive({
  companyName: '',
  companyFullName: '',
  inn: '',
  kpp: '',
  ogrn: '',
  legalAddress: '',
  bankName: '',
  bik: '',
  correspondentAccount: '',
  checkingAccount: '',
  signerFullName: '',
  signerPosition: '',
  signerBasis: '',
});

const profileFeedback = ref('');
const profileFeedbackTone = ref<'success' | 'error'>('success');

const profileQuery = useQuery(MyCounterpartyProfileDocument);
const saveCounterpartyMutation = useMutation(UpsertMyCounterpartyProfileDocument, { throws: 'never' });

const companySearch = ref('');
const partySuggestions = ref<PartySuggestion[]>([]);
const partyLoading = ref(false);
const partyOpen = ref(false);
const partySearchTimer = ref<ReturnType<typeof setTimeout> | null>(null);

const bankSearch = ref('');
const bankSuggestions = ref<BankSuggestion[]>([]);
const bankLoading = ref(false);
const bankOpen = ref(false);
const bankSearchTimer = ref<ReturnType<typeof setTimeout> | null>(null);

const partyDropdownRef = ref<HTMLElement | null>(null);
const bankDropdownRef = ref<HTMLElement | null>(null);

watch(
  () => profileQuery.result.value?.myCounterpartyProfile,
  (profile) => {
    if (!profile) {
      return;
    }

    counterpartyForm.companyName = profile.companyName;
    counterpartyForm.companyFullName = profile.companyFullName;
    counterpartyForm.inn = profile.inn;
    counterpartyForm.kpp = profile.kpp ?? '';
    counterpartyForm.ogrn = profile.ogrn ?? '';
    counterpartyForm.legalAddress = profile.legalAddress;
    counterpartyForm.bankName = profile.bankName;
    counterpartyForm.bik = profile.bik;
    counterpartyForm.correspondentAccount = profile.correspondentAccount;
    counterpartyForm.checkingAccount = profile.checkingAccount;
    counterpartyForm.signerFullName = profile.signerFullName;
    counterpartyForm.signerPosition = profile.signerPosition;
    counterpartyForm.signerBasis = profile.signerBasis;

    companySearch.value = profile.companyName;
    bankSearch.value = profile.bankName;
  },
  { immediate: true },
);

const profileUpdatedAt = computed(() => profileQuery.result.value?.myCounterpartyProfile?.updatedAt ?? null);
const profileIsComplete = computed(() => isCounterpartyProfileComplete(counterpartyForm));

function clearPartyTimer() {
  if (!partySearchTimer.value) {
    return;
  }
  clearTimeout(partySearchTimer.value);
  partySearchTimer.value = null;
}

function clearBankTimer() {
  if (!bankSearchTimer.value) {
    return;
  }
  clearTimeout(bankSearchTimer.value);
  bankSearchTimer.value = null;
}

async function fetchPartySuggestions() {
  const query = companySearch.value.trim();
  if (query.length < 2) {
    partySuggestions.value = [];
    partyOpen.value = false;
    return;
  }

  partyLoading.value = true;
  await $fetch<{ suggestions: PartySuggestion[] }>('/api/dadata/party', {
    method: 'POST',
    body: { query },
  })
    .then((response) => {
      partySuggestions.value = response.suggestions || [];
      partyOpen.value = partySuggestions.value.length > 0;
    })
    .finally(() => {
      partyLoading.value = false;
    });
}

async function fetchBankSuggestions() {
  const query = bankSearch.value.trim();
  if (query.length < 2) {
    bankSuggestions.value = [];
    bankOpen.value = false;
    return;
  }

  bankLoading.value = true;
  await $fetch<{ suggestions: BankSuggestion[] }>('/api/dadata/bank', {
    method: 'POST',
    body: { query },
  })
    .then((response) => {
      bankSuggestions.value = response.suggestions || [];
      bankOpen.value = bankSuggestions.value.length > 0;
    })
    .finally(() => {
      bankLoading.value = false;
    });
}

function schedulePartySuggest() {
  clearPartyTimer();
  partySearchTimer.value = setTimeout(() => {
    void fetchPartySuggestions();
  }, 250);
}

function scheduleBankSuggest() {
  clearBankTimer();
  bankSearchTimer.value = setTimeout(() => {
    void fetchBankSuggestions();
  }, 250);
}

function applyPartySuggestion(item: PartySuggestion) {
  partyOpen.value = false;
  companySearch.value = item.value;

  counterpartyForm.companyName = item.value;
  counterpartyForm.companyFullName = item.unrestricted_value || item.value;
  counterpartyForm.inn = item.data?.inn || '';
  counterpartyForm.kpp = item.data?.kpp || '';
  counterpartyForm.ogrn = item.data?.ogrn || '';
  counterpartyForm.legalAddress = item.data?.address?.value || '';

  if (!counterpartyForm.signerFullName && item.data?.management?.name) {
    counterpartyForm.signerFullName = item.data.management.name;
  }
  if (!counterpartyForm.signerPosition && item.data?.management?.post) {
    counterpartyForm.signerPosition = item.data.management.post;
  }
}

function applyBankSuggestion(item: BankSuggestion) {
  bankOpen.value = false;
  bankSearch.value = item.value;

  counterpartyForm.bankName = item.value;
  counterpartyForm.bik = item.data?.bic || '';
  counterpartyForm.correspondentAccount = item.data?.correspondent_account || '';
}

function closeDropdownsFromOutside(event: MouseEvent) {
  const target = event.target as Node | null;
  if (partyDropdownRef.value && target && !partyDropdownRef.value.contains(target)) {
    partyOpen.value = false;
  }
  if (bankDropdownRef.value && target && !bankDropdownRef.value.contains(target)) {
    bankOpen.value = false;
  }
}

async function saveCounterpartyProfile() {
  profileFeedback.value = '';
  const result = await saveCounterpartyMutation.mutate({
    input: {
      companyName: counterpartyForm.companyName,
      companyFullName: counterpartyForm.companyFullName,
      inn: counterpartyForm.inn,
      kpp: counterpartyForm.kpp.trim() ? counterpartyForm.kpp.trim() : null,
      ogrn: counterpartyForm.ogrn.trim() ? counterpartyForm.ogrn.trim() : null,
      legalAddress: counterpartyForm.legalAddress,
      bankName: counterpartyForm.bankName,
      bik: counterpartyForm.bik,
      correspondentAccount: counterpartyForm.correspondentAccount,
      checkingAccount: counterpartyForm.checkingAccount,
      signerFullName: counterpartyForm.signerFullName,
      signerPosition: counterpartyForm.signerPosition,
      signerBasis: counterpartyForm.signerBasis,
    },
  });

  const payload = result?.data?.upsertMyCounterpartyProfile;
  if (!payload) {
    profileFeedbackTone.value = 'error';
    profileFeedback.value = saveCounterpartyMutation.error.value?.message || 'Не удалось сохранить карточку контрагента.';
    return;
  }

  profileFeedbackTone.value = 'success';
  profileFeedback.value = 'Карточка контрагента сохранена.';
  await profileQuery.refetch();
}

onMounted(() => {
  document.addEventListener('click', closeDropdownsFromOutside);
});

onBeforeUnmount(() => {
  document.removeEventListener('click', closeDropdownsFromOutside);
  clearPartyTimer();
  clearBankTimer();
});
</script>

<template>
  <section class="space-y-6">
    <UiBackHeader
      to="/profile"
      back-label="Назад в профиль"
      title="Карточка контрагента"
      subtitle="Заполните реквизиты компании, банка и подписанта. После этого карточку можно будет использовать в заказах без ручного добивания данных."
    >
      <template #actions>
        <span
          class="inline-flex items-center rounded-full px-3 py-1 text-xs font-bold uppercase tracking-[0.16em]"
          :class="profileIsComplete ? 'bg-[#e8f6ee] text-[#0d854a]' : 'bg-[#fff3dc] text-[#b06b00]'"
        >
          {{ profileIsComplete ? 'Заполнено' : 'Нужно заполнить' }}
        </span>
      </template>
    </UiBackHeader>

    <div class="space-y-4">
      <section class="surface-card rounded-3xl p-5 md:p-6">
        <div class="mb-5 space-y-1">
          <h2 class="text-xl font-black tracking-[-0.02em] text-[#123824]">Данные компании</h2>
          <p class="text-sm leading-6 text-[#5c7b69]">
            Найдите компанию через DaData или заполните реквизиты вручную.
          </p>
        </div>

        <div class="grid gap-4">
          <div ref="partyDropdownRef" class="relative">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Поиск компании</span>
              <div class="relative">
                <input
                  v-model="companySearch"
                  type="text"
                  class="input manager-field w-full pr-11"
                  placeholder="Введите название компании или ИНН"
                  @input="schedulePartySuggest"
                  @focus="partyOpen = partySuggestions.length > 0"
                >
                <span v-if="partyLoading" class="loading loading-spinner loading-sm absolute right-4 top-1/2 -translate-y-1/2 text-[#5c7b69]" />
              </div>
            </label>

            <div
              v-if="partyOpen && partySuggestions.length > 0"
              class="absolute z-30 mt-2 max-h-72 w-full overflow-auto rounded-[1.4rem] border border-[#e1ebe4] bg-white p-2 shadow-[0_24px_48px_rgba(18,56,36,0.12)]"
            >
              <button
                v-for="item in partySuggestions"
                :key="`${item.value}-${item.data?.inn || ''}`"
                type="button"
                class="mb-1 w-full rounded-2xl px-4 py-3 text-left transition hover:bg-[#f5faf7]"
                @click="applyPartySuggestion(item)"
              >
                <span class="block text-sm font-semibold text-[#123824]">{{ item.value }}</span>
                <span class="mt-1 block text-xs text-[#5c7b69]">
                  ИНН: {{ item.data?.inn || '—' }}<span v-if="item.data?.kpp"> • КПП: {{ item.data.kpp }}</span>
                </span>
              </button>
            </div>
          </div>

          <div class="grid gap-4 md:grid-cols-2">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Краткое наименование</span>
              <input v-model="counterpartyForm.companyName" type="text" class="input manager-field w-full">
            </label>

            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Полное наименование</span>
              <input v-model="counterpartyForm.companyFullName" type="text" class="input manager-field w-full">
            </label>
          </div>

          <div class="grid gap-4 md:grid-cols-3">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">ИНН</span>
              <input v-model="counterpartyForm.inn" type="text" class="input manager-field w-full">
            </label>

            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">КПП</span>
              <input v-model="counterpartyForm.kpp" type="text" class="input manager-field w-full">
            </label>

            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">ОГРН</span>
              <input v-model="counterpartyForm.ogrn" type="text" class="input manager-field w-full">
            </label>
          </div>

          <label class="block space-y-2">
            <span class="text-sm font-semibold text-[#355947]">Юридический адрес</span>
            <textarea v-model="counterpartyForm.legalAddress" class="textarea manager-field min-h-28 w-full" />
          </label>
        </div>
      </section>

      <section class="surface-card rounded-3xl p-5 md:p-6">
        <div class="mb-5 space-y-1">
          <h2 class="text-xl font-black tracking-[-0.02em] text-[#123824]">Банковские реквизиты</h2>
          <p class="text-sm leading-6 text-[#5c7b69]">
            Подтяните банк по справочнику или внесите реквизиты вручную.
          </p>
        </div>

        <div class="grid gap-4">
          <div ref="bankDropdownRef" class="relative">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Поиск банка</span>
              <div class="relative">
                <input
                  v-model="bankSearch"
                  type="text"
                  class="input manager-field w-full pr-11"
                  placeholder="Введите название банка"
                  @input="scheduleBankSuggest"
                  @focus="bankOpen = bankSuggestions.length > 0"
                >
                <span v-if="bankLoading" class="loading loading-spinner loading-sm absolute right-4 top-1/2 -translate-y-1/2 text-[#5c7b69]" />
              </div>
            </label>

            <div
              v-if="bankOpen && bankSuggestions.length > 0"
              class="absolute z-30 mt-2 max-h-72 w-full overflow-auto rounded-[1.4rem] border border-[#e1ebe4] bg-white p-2 shadow-[0_24px_48px_rgba(18,56,36,0.12)]"
            >
              <button
                v-for="item in bankSuggestions"
                :key="`${item.value}-${item.data?.bic || ''}`"
                type="button"
                class="mb-1 w-full rounded-2xl px-4 py-3 text-left transition hover:bg-[#f5faf7]"
                @click="applyBankSuggestion(item)"
              >
                <span class="block text-sm font-semibold text-[#123824]">{{ item.value }}</span>
                <span class="mt-1 block text-xs text-[#5c7b69]">БИК: {{ item.data?.bic || '—' }}</span>
              </button>
            </div>
          </div>

          <div class="grid gap-4 md:grid-cols-2">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Банк</span>
              <input v-model="counterpartyForm.bankName" type="text" class="input manager-field w-full">
            </label>

            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">БИК</span>
              <input v-model="counterpartyForm.bik" type="text" class="input manager-field w-full">
            </label>
          </div>

          <div class="grid gap-4 md:grid-cols-2">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Корреспондентский счет</span>
              <input v-model="counterpartyForm.correspondentAccount" type="text" class="input manager-field w-full">
            </label>

            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Расчетный счет</span>
              <input v-model="counterpartyForm.checkingAccount" type="text" class="input manager-field w-full">
            </label>
          </div>
        </div>
      </section>

      <section class="surface-card rounded-3xl p-5 md:p-6">
        <div class="mb-5 space-y-1">
          <h2 class="text-xl font-black tracking-[-0.02em] text-[#123824]">Подписанты и основания</h2>
          <p class="text-sm leading-6 text-[#5c7b69]">
            Укажите, кто подписывает документы и на каком основании действует.
          </p>
        </div>

        <div class="grid gap-4">
          <div class="grid gap-4 md:grid-cols-2">
            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">ФИО подписанта</span>
              <input
                v-model="counterpartyForm.signerFullName"
                type="text"
                class="input manager-field w-full"
                placeholder="Иванов Иван Иванович"
              >
            </label>

            <label class="block space-y-2">
              <span class="text-sm font-semibold text-[#355947]">Должность</span>
              <input
                v-model="counterpartyForm.signerPosition"
                type="text"
                class="input manager-field w-full"
                placeholder="Генеральный директор"
              >
            </label>
          </div>

          <label class="block space-y-2">
            <span class="text-sm font-semibold text-[#355947]">Основание полномочий</span>
            <textarea
              v-model="counterpartyForm.signerBasis"
              class="textarea manager-field min-h-28 w-full"
              placeholder="Действует на основании Устава"
            />
          </label>
        </div>

        <div class="mt-6 flex flex-col gap-3 border-t border-[#edf2ee] pt-5 md:flex-row md:items-center md:justify-between">
          <div class="space-y-1">
            <p class="text-sm font-semibold text-[#123824]">
              {{ profileIsComplete ? 'Карточка готова к использованию в заказах.' : 'Заполните обязательные поля, чтобы сохранить карточку.' }}
            </p>
            <p v-if="profileUpdatedAt" class="text-xs text-[#6f8579]">
              Обновлено: {{ new Date(profileUpdatedAt).toLocaleString() }}
            </p>
          </div>

          <button
            class="btn h-12 w-full rounded-full border-0 bg-[#123824] px-7 text-white shadow-[0_18px_34px_rgba(18,56,36,0.18)] hover:bg-[#0f2f20] disabled:border-0 disabled:bg-[#cfd8d2] disabled:text-[#6f8579] md:w-auto"
            :disabled="saveCounterpartyMutation.loading.value || !profileIsComplete"
            @click="saveCounterpartyProfile"
          >
            {{ saveCounterpartyMutation.loading.value ? 'Сохраняем…' : 'Сохранить карточку' }}
          </button>
        </div>
      </section>

      <div v-if="profileFeedback" class="alert" :class="profileFeedbackTone === 'success' ? 'alert-success' : 'alert-error'">
        {{ profileFeedback }}
      </div>
    </div>
  </section>
</template>
