<template>
  <div class="tw:flex tw:flex-col tw:h-[calc(100vh-200px)] tw:gap-4">
    <!-- Popup подтверждения очистки -->
    <ConfirmPopup group="clearForm" />
    <!-- Диалог предупреждения при смене режима -->
    <ConfirmDialog group="modeSwitch">
      <template #message="{ message }">
         <div class="tw:whitespace-pre-wrap tw:max-w-lg">{{ message.message }}</div>
      </template>
    </ConfirmDialog>

    <!-- Панель инструментов -->
    <div class="tw:flex tw:justify-start tw:items-center tw:pb-2 tw:border-b tw:border-gray-200">

      <!-- Переключатель режимов -->
      <SelectButton
        :key="selectButtonKey"
        :modelValue="activeMode"
        :options="modes"
        optionLabel="label"
        optionValue="value"
        :allowEmpty="false"
        @update:modelValue="handleModeChange"
      >
         <template #option="slotProps">
            <i :class="slotProps.option.icon" class="tw:mr-2"></i>
            <span>{{ slotProps.option.label }}</span>
        </template>
      </SelectButton>
    </div>

    <div class="tw:flex tw:flex-1 tw:gap-4 tw:overflow-hidden tw:min-h-0">

      <!-- Режим визуального конструктора -->
      <template v-if="activeMode === 'visual'">
        <!-- Панель доступных полей -->
        <div class="tw:w-64 tw:flex-shrink-0 tw:h-full tw:overflow-hidden">
             <FieldsPanel class="tw:h-full" />
        </div>

        <!-- Основная зона конструктора -->
        <div class="tw:flex-1 tw:flex tw:gap-4 tw:overflow-hidden">
            <!-- Зона формы -->
            <div class="tw:flex-1 tw:flex tw:flex-col tw:border tw:border-gray-200 tw:rounded-lg tw:overflow-hidden tw:bg-white tw:relative">
              <!-- Кнопка очистки (абсолютно позиционирована) -->
              <div class="tw:absolute tw:top-4 tw:right-4 tw:z-20">
                 <Button
                   label="Очистить"
                   icon="fa fa-trash"
                   severity="danger"
                   size="small"
                   text
                   v-tooltip.left="'Удалить все поля и очистить форму'"
                   @click="clearForm"
                 />
              </div>

              <!-- Контент (FormCanvas) занимает все оставшееся пространство -->
              <div class="tw:flex-1 tw:overflow-y-auto tw:relative">
                <FormCanvas class="tw:min-h-full" />
              </div>
            </div>

            <!-- Панель настроек (справа) -->
            <div class="tw:w-80 tw:flex-shrink-0 tw:h-full tw:overflow-y-auto">
              <Panel class="tw:min-h-full">
                <template #header>
                  <span>Настройки поля</span>
                </template>
                <FieldSettings />
              </Panel>
            </div>
        </div>
      </template>

      <!-- Режим редактирования кода -->
      <template v-if="activeMode === 'code'">
        <CodeEditor
          v-model="jsonCode"
          :error="jsonError"
          :is-custom="isCustom"
          @change="handleJsonInput"
        />
      </template>

      <!-- Режим предпросмотра -->
      <template v-if="activeMode === 'preview'">
        <div class="tw:flex-1 tw:flex tw:justify-center tw:overflow-auto">
          <div class="tw:w-full">
            <FormRenderer
              :schema="formSchema"
              submit-label="Отправить форму"
              @submit="handleFormSubmit"
            />
          </div>
        </div>
      </template>

    </div>
  </div>
</template>

<script setup>
import { ref, provide, computed, onMounted } from 'vue';
import { Button, Panel, SelectButton, useConfirm, ConfirmPopup, ConfirmDialog } from 'primevue';
import FieldsPanel from '@/components/FormBuilder/FieldsPanel.vue';
import FormCanvas from '@/components/FormBuilder/FormCanvas.vue';
import FieldSettings from '@/components/FormBuilder/FieldSettings.vue';
import FormRenderer from '@/components/FormBuilder/FormRenderer.vue';
import CodeEditor from '@/components/FormBuilder/CodeEditor.vue';
import { toastBus } from '@/utils/toastHelper';

const formFields = defineModel({
  type: Array,
  default: () => []
});

const isCustom = defineModel('isCustom', {
  type: Boolean,
  default: false
});

const activeMode = ref('visual');
const jsonCode = ref('');
const originalJsonCode = ref(''); // Для отслеживания изменений в режиме кода
const jsonError = ref(null);
const confirm = useConfirm();
const selectButtonKey = ref(0);

const modes = [
  { label: 'Визуальный', value: 'visual', icon: 'fa fa-th-large' },
  { label: 'Код', value: 'code', icon: 'fa fa-code' },
  { label: 'Предпросмотр', value: 'preview', icon: 'fa fa-eye' },
];

// Состояние выбранного поля
const selectedFieldId = ref(null);

// Состояние ошибок полей
const fieldErrors = ref({});

// Предоставляем состояние дочерним компонентам
provide('formFields', formFields);
provide('selectedFieldId', selectedFieldId);
provide('fieldErrors', fieldErrors);

// Схема формы для предпросмотра
const formSchema = computed(() => {
  return formFields.value || [];
});

// Инициализация режима при монтировании
onMounted(() => {
  if (isCustom.value) {
    activeMode.value = 'code';
    jsonCode.value = JSON.stringify(formFields.value, null, 2);
    originalJsonCode.value = jsonCode.value;
  } else {
    activeMode.value = 'visual';
  }
});

function hasDuplicateNames(fields) {
  if (!Array.isArray(fields)) return false;
  const names = new Set();
  for (const field of fields) {
    if (field.name) {
      if (names.has(field.name)) {
        return true;
      }
      names.add(field.name);
    }
  }
  return false;
}

function cancelModeSwitch() {
    // Инкементируем ключ, чтобы принудительно перерисовать SelectButton с текущим activeMode
    selectButtonKey.value++;
}

function handleModeChange(newMode) {
  // Если пытаемся переключиться на тот же режим
  if (newMode === activeMode.value) return;

  // Если переключаемся ИЗ режима кода
  if (activeMode.value === 'code') {
    // Пытаемся распарсить JSON перед уходом
    if (jsonError.value) {
      toastBus.emit('show', { severity: 'error', summary: 'Ошибка JSON', detail: 'Исправьте ошибки в JSON перед переключением режима' });
      // Не обновляем activeMode, остаемся в code
      cancelModeSwitch();
      return;
    }

    try {
         const parsed = JSON.parse(jsonCode.value);

         if (hasDuplicateNames(parsed)) {
            toastBus.emit('show', { severity: 'error', summary: 'Ошибка валидации', detail: 'В схеме есть поля с одинаковыми именами (name). Исправьте их перед переключением.' });
            cancelModeSwitch();
            return;
         }

         // Проверяем, были ли изменения в коде
         let hasChanges = false;
         try {
             // Сравниваем распарсенные объекты, чтобы избежать ложных срабатываний из-за форматирования
             const originalObj = JSON.parse(originalJsonCode.value);
             hasChanges = JSON.stringify(parsed) !== JSON.stringify(originalObj);
         } catch (e) {
             hasChanges = true; // Если не смогли распарсить оригинал, считаем что изменения были (или ошибка)
         }

         // Если переключаемся в визуальный режим
         if (newMode === 'visual') {
             if (hasChanges) {
                 // Если были изменения, показываем предупреждение
                 confirm.require({
                     group: 'modeSwitch',
                     header: 'Предупреждение',
                     message: 'Вы внесли изменения в код вручную.\n\nПосле ручного изменения визуальный редактор может работать некорректно или не отображать все настройки.\n\nВы можете остаться в режиме кода или очистить форму и начать заново в визуальном редакторе.',
                     icon: 'fa fa-exclamation-triangle',
                     acceptLabel: 'Очистить и перейти',
                     rejectLabel: 'Остаться в коде',
                     acceptClass: 'p-button-danger',
                     accept: () => {
                         formFields.value = [];
                         selectedFieldId.value = null;
                         isCustom.value = false;
                         jsonCode.value = '[]';

                         // Успешный переход
                         activeMode.value = 'visual';
                     },
                     reject: () => {
                         // Остаемся в коде
                         // activeMode.value НЕ обновляем, он остался 'code'
                         cancelModeSwitch();
                     }
                 });

                 // Не обновляем activeMode сразу, ждем решения пользователя
                 return;
             } else {
                 // Если изменений не было, просто переключаемся и сбрасываем флаг кастомного режима
                 isCustom.value = false;
                 formFields.value = parsed;
             }
         } else {
            // Переход в Preview - разрешаем обновление модели из кода
             console.log('Updating formFields for Preview:', parsed);
             formFields.value = parsed;
         }

    } catch (e) {
         console.error('Ошибка парсинга при переключении:', e);
          toastBus.emit('show', { severity: 'error', summary: 'Ошибка', detail: 'Некорректный JSON' });
          cancelModeSwitch();
          return;
    }
  }

  // Если переключаемся В режим кода
  if (newMode === 'code') {
    isCustom.value = true;
    jsonCode.value = JSON.stringify(formFields.value, null, 2);
    originalJsonCode.value = jsonCode.value; // Сохраняем исходное состояние
  }

  // Обновляем режим для успешных переходов
  activeMode.value = newMode;
}


function handleJsonInput() {
  try {
    const parsed = JSON.parse(jsonCode.value);

    if (hasDuplicateNames(parsed)) {
       jsonError.value = 'Ошибка: найдены поля с одинаковыми именами (name)';
    } else {
       jsonError.value = null;
    }

    // Обновляем модель сразу, чтобы изменения не терялись
    console.log('handleJsonInput: Updating formFields', parsed);
    formFields.value = parsed;
  } catch (e) {
    jsonError.value = e.message;
  }
}

function clearForm(event) {
  confirm.require({
    target: event.currentTarget,
    group: 'clearForm',
    message: 'Вы уверены, что хотите очистить форму? Все поля будут удалены.',
    icon: 'fa fa-exclamation-triangle',
    acceptLabel: 'Да, очистить',
    rejectLabel: 'Нет',
    acceptClass: 'p-button-danger p-button-sm',
    rejectClass: 'p-button-secondary p-button-sm p-button-text',
    accept: () => {
      formFields.value = [];
      selectedFieldId.value = null;
      jsonCode.value = '[]';
      toastBus.emit('show', { severity: 'success', summary: 'Успешно', detail: 'Форма очищена' });
    }
  });
}

function handleFormSubmit(data) {
  console.log('Данные формы:', data);
  toastBus.emit('show', { severity: 'success', summary: 'Форма отправлена', detail: 'Данные: ' + JSON.stringify(data, null, 2) });
}
</script>

<style scoped>
</style>
