<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 v-if="isCustom" class="tw:flex-1 tw:flex tw:items-center tw:justify-center">
          <div class="tw:max-w-2xl tw:p-8 tw:bg-yellow-50 tw:border-2 tw:border-yellow-200 tw:rounded-lg">
            <div class="tw:flex tw:items-start tw:gap-4">
              <i class="fa fa-exclamation-triangle tw:text-3xl tw:text-yellow-600"></i>
              <div>
                <h3 class="tw:text-lg tw:font-bold tw:text-yellow-800 tw:mb-2">
                  Форма является кастомной
                </h3>
                <p class="tw:text-yellow-700 tw:mb-4">
                  Эта форма была создана или изменена вручную в редакторе кода и не может быть отображена в визуальном редакторе.
                </p>
                <p class="tw:text-yellow-700 tw:mb-4">
                  Для работы с этой формой используйте режим "Код". Если вы хотите создать новую форму в визуальном редакторе, необходимо сбросить текущую форму.
                </p>
                <Button
                  label="Перейти в режим кода"
                  icon="fa fa-code"
                  @click="activeMode = 'code'"
                  class="tw:mr-2"
                />
                <Button
                  label="Сбросить и создать новую"
                  icon="fa fa-trash"
                  severity="danger"
                  outlined
                  @click="showResetConfirmation"
                />
              </div>
            </div>
          </div>
        </div>
        
        <!-- Обычный визуальный редактор для некстомных форм -->
        <template v-else>
          <!-- Панель доступных полей -->
          <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>

      <!-- Режим редактирования кода -->
      <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">
            <div v-if="jsonError" class="tw:p-4 tw:bg-red-50 tw:border tw:border-red-200 tw:rounded tw:text-red-700">
              <i class="fa fa-exclamation-circle tw:mr-2"></i>
              Ошибка в схеме: {{ jsonError }}
            </div>
            <FormRenderer
              v-else
              :schema="formSchema"
              submit-label="Отправить форму"
              @submit="handleFormSubmit"
            />
          </div>
        </div>
      </template>

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

<script setup>
import { ref, provide, computed, onMounted, watch } 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';
import { saveRevision } from './utils/revisionManager.js';
import { createEmptySchema } from './utils/schemaParser.js';

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

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

// Локальные состояния (не сохраняются в БД)
const dirtyFromCode = ref(false);
const lastSyncedSchema = ref(null);

const activeMode = ref('visual');
const jsonCode = ref('');
const jsonError = ref(null);
const confirm = useConfirm();
const selectButtonKey = ref(0);

// Алиас формы для сохранения ревизий (можно передавать через props, пока используем 'checkout')
const formAlias = 'checkout';

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(() => {
  initializeForm();
});

// Инициализация формы при загрузке из БД
function initializeForm() {
  const schema = formFields.value || [];
  
  // Устанавливаем lastSyncedSchema равным загруженной схеме
  lastSyncedSchema.value = JSON.parse(JSON.stringify(schema));
  
  // dirtyFromCode всегда false при загрузке
  dirtyFromCode.value = false;
  
  // Определяем начальный режим на основе isCustom
  if (isCustom.value) {
    activeMode.value = 'code';
    jsonCode.value = JSON.stringify(schema, null, 2);
  } else {
    activeMode.value = 'visual';
    jsonCode.value = JSON.stringify(schema, null, 2);
  }
}

// Отслеживание изменений в визуальном редакторе
watch(formFields, (newSchema) => {
  // Если мы в визуальном режиме и форма не кастомная, обновляем lastSyncedSchema
  if (activeMode.value === 'visual' && !dirtyFromCode.value && !isCustom.value) {
    lastSyncedSchema.value = JSON.parse(JSON.stringify(newSchema));
    // Обновляем jsonCode для синхронизации
    jsonCode.value = JSON.stringify(newSchema, null, 2);
  }
}, { deep: true });

// Отслеживание изменений isCustom для переинициализации
watch(isCustom, () => {
  // При изменении isCustom извне (например, при загрузке из БД) переинициализируем
  if (activeMode.value === 'code' && !isCustom.value) {
    // Если isCustom стал false, но мы в режиме кода, это значит форма была сброшена
    // Синхронизируем состояния
    lastSyncedSchema.value = JSON.parse(JSON.stringify(formFields.value));
    dirtyFromCode.value = false;
  }
});

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 перед переключением режима' });
      cancelModeSwitch();
      return;
    }

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

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

      // Если переключаемся в визуальный режим
      if (newMode === 'visual') {
        // Проверяем, нужно ли показывать предупреждение
        const needsWarning = isCustom.value || dirtyFromCode.value;

        if (needsWarning) {
          // Сохраняем ревизию перед деструктивной операцией
          saveRevision(formAlias, formFields.value, 'reset_to_visual');

          // Показываем предупреждение
          confirm.require({
            group: 'modeSwitch',
            header: 'Предупреждение',
            message: isCustom.value 
              ? 'Загруженная форма является кастомной и может содержать неподдерживаемые элементы.\n\nОткрытие визуального редактора приведет к полному сбросу формы. Все нестандартные настройки будут потеряны.'
              : 'Форма была изменена вручную в редакторе кода.\n\nВизуальный редактор не поддерживает все конструкции, и для его открытия потребуется полностью сбросить форму и создать новую. Все нестандартные настройки будут потеряны.',
            icon: 'fa fa-exclamation-triangle',
            acceptLabel: 'Сбросить и открыть визуальный редактор',
            rejectLabel: 'Отменить',
            acceptClass: 'p-button-danger',
            accept: () => {
              resetFormToVisual();
              activeMode.value = 'visual';
            },
            reject: () => {
              cancelModeSwitch();
            }
          });

          return;
        } else {
          // Если isCustom=false и dirtyFromCode=false, просто переключаемся
          // Обновляем схему из кода
          formFields.value = parsed;
          lastSyncedSchema.value = JSON.parse(JSON.stringify(parsed));
          dirtyFromCode.value = false;
        }
      } else if (newMode === 'preview') {
        // Переход в Preview - обновляем модель из кода
        formFields.value = parsed;
      }
    } catch (e) {
      console.error('Ошибка парсинга при переключении:', e);
      toastBus.emit('show', { severity: 'error', summary: 'Ошибка', detail: 'Некорректный JSON' });
      cancelModeSwitch();
      return;
    }
  }

  // Если переключаемся В режим кода
  if (newMode === 'code') {
    // Обновляем jsonCode из текущей схемы
    jsonCode.value = JSON.stringify(formFields.value, null, 2);
    // Обновляем lastSyncedSchema, если мы пришли из визуального редактора
    if (activeMode.value === 'visual') {
      lastSyncedSchema.value = JSON.parse(JSON.stringify(formFields.value));
      dirtyFromCode.value = false;
    }
    // isCustom не меняем автоматически при переходе в режим кода
    // Он установится в true только когда пользователь реально изменит код (через handleJsonInput)
  }

  // Если переключаемся В визуальный режим из preview
  if (newMode === 'visual' && activeMode.value === 'preview') {
    // Никаких проверок, просто переключаемся
  }

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

/**
 * Сбрасывает форму для визуального редактора
 */
function resetFormToVisual() {
  // Сохраняем ревизию (уже сохранена выше, но на всякий случай)
  saveRevision(formAlias, formFields.value, 'reset_to_visual');

  // Создаем пустую схему
  const emptySchema = createEmptySchema();
  
  // Обновляем все состояния
  formFields.value = emptySchema;
  selectedFieldId.value = null;
  isCustom.value = false;
  jsonCode.value = JSON.stringify(emptySchema, null, 2);
  lastSyncedSchema.value = JSON.parse(JSON.stringify(emptySchema));
  dirtyFromCode.value = false;
}

/**
 * Показывает подтверждение сброса формы
 */
function showResetConfirmation() {
  // Сохраняем ревизию перед деструктивной операцией
  saveRevision(formAlias, formFields.value, 'reset_to_visual');

  confirm.require({
    group: 'modeSwitch',
    header: 'Подтверждение сброса',
    message: 'Вы уверены, что хотите сбросить кастомную форму и создать новую в визуальном редакторе?\n\nВсе текущие настройки будут потеряны.',
    icon: 'fa fa-exclamation-triangle',
    acceptLabel: 'Сбросить и создать новую',
    rejectLabel: 'Отменить',
    acceptClass: 'p-button-danger',
    accept: () => {
      resetFormToVisual();
      activeMode.value = 'visual';
    },
    reject: () => {
      // Отменяем действие
    }
  });
}


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

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

    // Обновляем модель сразу, чтобы изменения не терялись
    formFields.value = parsed;

    // Проверяем, изменилась ли схема относительно lastSyncedSchema
    if (lastSyncedSchema.value !== null) {
      const currentSchemaStr = JSON.stringify(parsed);
      const lastSyncedStr = JSON.stringify(lastSyncedSchema.value);
      const hasChanges = currentSchemaStr !== lastSyncedStr;
      dirtyFromCode.value = hasChanges;
      
      // Если есть изменения и форма еще не кастомная, устанавливаем isCustom=true
      if (hasChanges && !isCustom.value) {
        isCustom.value = true;
      }
    } else {
      // Если lastSyncedSchema еще не установлен, считаем что изменения есть
      dirtyFromCode.value = true;
      if (!isCustom.value) {
        isCustom.value = true;
      }
    }
  } catch (e) {
    jsonError.value = e.message;
    // При ошибке парсинга не обновляем dirtyFromCode и isCustom
  }
}

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: () => {
      // Сохраняем ревизию перед очисткой
      saveRevision(formAlias, formFields.value, 'clear_form');
      
      const emptySchema = createEmptySchema();
      formFields.value = emptySchema;
      selectedFieldId.value = null;
      jsonCode.value = JSON.stringify(emptySchema, null, 2);
      lastSyncedSchema.value = JSON.parse(JSON.stringify(emptySchema));
      dirtyFromCode.value = false;
      // После очистки в визуальном редакторе форма не кастомная
      isCustom.value = false;
      
      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>
