<script setup lang="ts">
import { useMutation, useQuery } from '@vue/apollo-composable';
import {
  CatalogProductTypeSettingsDocument,
  UpsertCatalogProductTypeSettingDocument,
  type CatalogProductTypeSettingsQuery,
} from '~/composables/graphql/generated';

definePageMeta({
  middleware: ['manager-only'],
  path: '/admin/settings/catalog',
});

type CatalogSettingItem = CatalogProductTypeSettingsQuery['catalogProductTypeSettings'][number];
type CatalogSettingForm = {
  productType: string;
  allowCustomLength: boolean;
  customLengthMinM: string;
  customLengthMaxM: string;
  customLengthStepM: string;
  allowCustomSleeveBrand: boolean;
  allowCustomLabel: boolean;
};

const settingsQuery = useQuery(CatalogProductTypeSettingsDocument);
const saveSettingMutation = useMutation(UpsertCatalogProductTypeSettingDocument, { throws: 'never' });

const forms = reactive<Record<string, CatalogSettingForm>>({});
const isSavingAll = ref(false);
const saveSuccess = ref('');
const saveError = ref('');

const settings = computed<CatalogSettingItem[]>(() => settingsQuery.result.value?.catalogProductTypeSettings ?? []);

function toInputValue(value: number | null | undefined) {
  return value == null ? '' : String(value);
}

function createForm(item: CatalogSettingItem): CatalogSettingForm {
  return {
    productType: item.productType,
    allowCustomLength: item.allowCustomLength,
    customLengthMinM: toInputValue(item.customLengthMinM),
    customLengthMaxM: toInputValue(item.customLengthMaxM),
    customLengthStepM: toInputValue(item.customLengthStepM),
    allowCustomSleeveBrand: item.allowCustomSleeveBrand,
    allowCustomLabel: item.allowCustomLabel,
  };
}

function parseOptionalInteger(value: string) {
  const normalized = value.trim();
  if (!normalized) {
    return null;
  }

  return Number(normalized);
}

function formFor(item: CatalogSettingItem) {
  forms[item.productType] ??= createForm(item);
  return forms[item.productType];
}

watch(
  settings,
  (items) => {
    const activeTypes = new Set(items.map((item) => item.productType));

    for (const productType of Object.keys(forms)) {
      if (!activeTypes.has(productType)) {
        Reflect.deleteProperty(forms, productType);
      }
    }

    for (const item of items) {
      forms[item.productType] = createForm(item);
    }
  },
  { immediate: true },
);

async function saveAllSettings() {
  saveSuccess.value = '';
  saveError.value = '';
  isSavingAll.value = true;

  for (const item of settings.value) {
    const form = formFor(item);
    const result = await saveSettingMutation.mutate({
      input: {
        productType: form.productType,
        showQuantityPerBox: false,
        allowCustomLength: form.allowCustomLength,
        customLengthMinM: form.allowCustomLength ? parseOptionalInteger(form.customLengthMinM) : null,
        customLengthMaxM: form.allowCustomLength ? parseOptionalInteger(form.customLengthMaxM) : null,
        customLengthStepM: form.allowCustomLength ? parseOptionalInteger(form.customLengthStepM) : null,
        allowCustomSleeveBrand: form.allowCustomSleeveBrand,
        allowCustomLabel: form.allowCustomLabel,
      },
    });

    if (!result?.data?.upsertCatalogProductTypeSetting) {
      saveError.value = saveSettingMutation.error.value?.message || `Не удалось сохранить настройки для "${form.productType}".`;
      isSavingAll.value = false;
      return;
    }

    forms[item.productType] = createForm(result.data.upsertCatalogProductTypeSetting);
  }

  isSavingAll.value = false;
  saveSuccess.value = 'Настройки сохранены.';
}
</script>

<template>
  <section class="space-y-6">
    <h1 class="text-3xl font-extrabold text-[#0f2f20]">Каталог</h1>

    <div v-if="settingsQuery.loading.value" class="manager-empty-state">
      Загружаем настройки каталога...
    </div>

    <div v-else-if="settings.length === 0" class="manager-empty-state">
      Типы товаров пока не появились в каталоге.
    </div>

    <div v-else class="grid gap-4 xl:grid-cols-2">
      <article
        v-for="item in settings"
        :key="item.productType"
        class="rounded-[28px] bg-white p-5 shadow-[0_18px_38px_rgba(18,56,36,0.08)]"
      >
        <div class="flex flex-col gap-4">
          <h2 class="text-xl font-bold text-[#123824]">{{ item.productType }}</h2>

          <div class="grid gap-3 md:grid-cols-2">
            <label class="surface-card flex items-center justify-between gap-4 rounded-[22px] p-4">
              <span class="text-sm font-semibold text-[#123824]">Любая длина</span>
              <input v-model="formFor(item).allowCustomLength" type="checkbox" class="toggle toggle-success">
            </label>

            <label class="surface-card flex items-center justify-between gap-4 rounded-[22px] p-4">
              <span class="text-sm font-semibold text-[#123824]">Втулка с логотипом</span>
              <input v-model="formFor(item).allowCustomSleeveBrand" type="checkbox" class="toggle toggle-success">
            </label>

            <label class="surface-card flex items-center justify-between gap-4 rounded-[22px] p-4">
              <span class="text-sm font-semibold text-[#123824]">Нанесение надписи</span>
              <input v-model="formFor(item).allowCustomLabel" type="checkbox" class="toggle toggle-success">
            </label>
          </div>

          <div v-if="formFor(item).allowCustomLength" class="rounded-[24px] bg-[#f7fbf8] p-4">
            <div class="mb-4 text-sm font-bold uppercase tracking-[0.12em] text-[#355947]">Диапазон длины</div>
            <div class="grid gap-3 md:grid-cols-3">
              <label class="space-y-2">
                <span class="text-sm font-semibold text-[#123824]">Мин. длина, м</span>
                <input
                  v-model="formFor(item).customLengthMinM"
                  type="number"
                  min="1"
                  step="1"
                  class="input manager-field w-full"
                >
              </label>

              <label class="space-y-2">
                <span class="text-sm font-semibold text-[#123824]">Макс. длина, м</span>
                <input
                  v-model="formFor(item).customLengthMaxM"
                  type="number"
                  min="1"
                  step="1"
                  class="input manager-field w-full"
                >
              </label>

              <label class="space-y-2">
                <span class="text-sm font-semibold text-[#123824]">Шаг, м</span>
                <input
                  v-model="formFor(item).customLengthStepM"
                  type="number"
                  min="1"
                  step="1"
                  class="input manager-field w-full"
                >
              </label>
            </div>
          </div>
        </div>
      </article>
    </div>

    <div v-if="saveSuccess || saveError" class="space-y-2 text-sm">
      <p v-if="saveSuccess" class="font-semibold text-[#1c6b45]">{{ saveSuccess }}</p>
      <p v-if="saveError" class="font-semibold text-[#c4472d]">{{ saveError }}</p>
    </div>

    <div v-if="settings.length" class="flex justify-end">
      <button
        class="btn h-11 rounded-full border-0 bg-[#139957] px-6 text-sm font-semibold text-white hover:bg-[#0d854a]"
        :disabled="isSavingAll"
        @click="saveAllSettings"
      >
        {{ isSavingAll ? 'Сохраняем…' : 'Сохранить' }}
      </button>
    </div>
  </section>
</template>
