<!--
  Copyright (c) 2024-2026 Тарабанов Александр Викторович
  All rights reserved.
  
  This software is proprietary and confidential.
  Unauthorized copying, modification, or distribution is prohibited.
  
  For licensing inquiries: info@hb3-accelerator.com
  Website: https://hb3-accelerator.com
  GitHub: https://github.com/VC-HB3-Accelerator
-->

<template>
  <template v-if="column.type === 'multiselect'">
    <div v-if="!editing" @click="canEditData && (editing = true)" class="tags-cell-view">
      <span v-if="selectedMultiNames.length">{{ selectedMultiNames.join(', ') }}</span>
      <span v-else class="cell-plus-icon" title="Добавить">
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
          <circle cx="9" cy="9" r="8" fill="#f3f4f6" stroke="#b6c6e6"/>
          <rect x="8" y="4" width="2" height="10" rx="1" fill="#4f8cff"/>
          <rect x="4" y="8" width="10" height="2" rx="1" fill="#4f8cff"/>
        </svg>
      </span>
    </div>
    <div v-else class="tags-cell-edit">
      <div class="tags-multiselect">
        <div v-for="option in multiOptions" :key="option" class="tag-option">
          <input type="checkbox" :id="'cell-multi-' + option + '-' + rowId" :value="option" v-model="editMultiValues" />
          <label :for="'cell-multi-' + option + '-' + rowId">{{ option }}</label>
          <span class="remove-option" @click.stop="removeMultiOption(option)">✕</span>
        </div>
      </div>
      <div class="add-multiselect-option">
        <input v-model="newMultiOption" @keyup.enter="addMultiOption" placeholder="Новое значение" />
        <button class="add-btn" @click="addMultiOption">+</button>
      </div>
      <button class="save-btn" @click="saveMulti">Сохранить</button>
      <button class="cancel-btn" @click="cancelMulti">Отмена</button>
    </div>
  </template>
  <template v-else-if="column.type === 'relation'">
    <div v-if="!editing" @click="canEditData && (editing = true)" class="tags-cell-view">
      <span v-if="selectedRelationName">{{ selectedRelationName }}</span>
      <span v-else class="cell-plus-icon" title="Добавить">
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
          <circle cx="9" cy="9" r="8" fill="#f3f4f6" stroke="#b6c6e6"/>
          <rect x="8" y="4" width="2" height="10" rx="1" fill="#4f8cff"/>
          <rect x="4" y="8" width="10" height="2" rx="1" fill="#4f8cff"/>
        </svg>
      </span>
    </div>
    <div v-else class="tags-cell-edit">
      <select v-model="editRelationValue" class="notion-input">
        <option v-for="opt in relationOptions" :key="opt.id" :value="opt.id">{{ opt.display }}</option>
      </select>
      <button class="save-btn" @click="saveRelation">Сохранить</button>
      <button class="cancel-btn" @click="cancelRelation">Отмена</button>
    </div>
  </template>
  <template v-else-if="column.type === 'lookup'">
    <div class="lookup-cell-view">
      <span v-if="lookupValues.length">{{ lookupValues.join(', ') }}</span>
      <span v-else style="color:#bbb">—</span>
    </div>
  </template>
  <template v-else-if="column.type === 'multiselect-relation'">
    <div v-if="!editing" @click="canEditData && (editing = true)" class="tags-cell-view">
      <span v-if="selectedMultiRelationNames.length">{{ selectedMultiRelationNames.join(', ') }}</span>
      <span v-else class="cell-plus-icon" title="Добавить">
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
          <circle cx="9" cy="9" r="8" fill="#f3f4f6" stroke="#b6c6e6"/>
          <rect x="8" y="4" width="2" height="10" rx="1" fill="#4f8cff"/>
          <rect x="4" y="8" width="10" height="2" rx="1" fill="#4f8cff"/>
        </svg>
      </span>
    </div>
    <div v-else class="tags-cell-edit">
      <div class="tags-multiselect">
        <div v-for="option in multiRelationOptions" :key="option.id" class="tag-option">
          <input type="checkbox" :id="'cell-multirel-' + option.id + '-' + rowId" :value="String(option.id)" v-model="editMultiRelationValues" />
          <label :for="'cell-multirel-' + option.id + '-' + rowId">{{ option.display }}</label>
          <button class="delete-tag-btn" @click.prevent="deleteTag(option.id)" title="Удалить тег">×</button>
        </div>
      </div>
      <div class="add-tag-block">
        <button v-if="!showAddTagInput" class="add-tag-btn" @click="showAddTagInput = true">+ Новый тег</button>
        <div v-else class="add-tag-form">
          <input v-model="newTagName" @keyup.enter="addTag" placeholder="Название тега" />
          <button class="add-tag-confirm" @click="addTag">Добавить</button>
          <button class="add-tag-cancel" @click="showAddTagInput = false; newTagName = ''">×</button>
        </div>
      </div>
      <div class="action-buttons">
        <button class="save-btn" @click="saveMultiRelation">Сохранить</button>
        <button class="cancel-btn" @click="cancelMultiRelation">Отмена</button>
      </div>
    </div>
  </template>
  <template v-else>
    <div v-if="!editing" class="cell-view-value" @click="canEditData && (editing = true)">
    <span v-if="isArrayString(localValue)">{{ parseArrayString(localValue).join(', ') }}</span>
      <span v-else-if="localValue">{{ localValue }}</span>
      <span v-else class="cell-plus-icon" title="Добавить">
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none">
          <circle cx="9" cy="9" r="8" fill="#f3f4f6" stroke="#b6c6e6"/>
          <rect x="8" y="4" width="2" height="10" rx="1" fill="#4f8cff"/>
          <rect x="4" y="8" width="10" height="2" rx="1" fill="#4f8cff"/>
        </svg>
      </span>
    </div>
    <textarea
      v-else
      v-model="localValue"
      @blur="saveAndExit"
      @keyup.enter="saveAndExit"
      :placeholder="column.name"
      class="cell-input"
      autofocus
      ref="textareaRef"
      @input="autoResize"
    />
  </template>
</template>

<script setup>
import { ref, watch, onMounted, computed, nextTick, onUnmounted } from 'vue';
import tablesService from '../../services/tablesService';
import { useTablesWebSocket } from '../../composables/useTablesWebSocket';
import { useTagsWebSocket } from '../../composables/useTagsWebSocket';
import cacheService from '../../services/cacheService';
import { usePermissions } from '@/composables/usePermissions';

const props = defineProps(['rowId', 'column', 'cellValues']);
const emit = defineEmits(['update']);
const { canEditData } = usePermissions();

const localValue = ref('');
const editing = ref(false);
// const allTags = ref([]); // Все теги из /api/tags
const editTagIds = ref([]); // id выбранных тегов в режиме редактирования

// Для отображения выбранных тегов
const selectedTagNames = ref([]);

const multiOptions = ref([]);
const editMultiValues = ref([]);
const selectedMultiNames = ref([]);
const newMultiOption = ref('');
// relation/lookup
const relationOptions = ref([]);
const editRelationValue = ref(null);
const selectedRelationName = ref('');
const lookupValues = ref([]);

const multiRelationOptions = ref([]);
const editMultiRelationValues = ref([]);
const selectedMultiRelationNames = ref([]);

const showAddTagInput = ref(false);
const newTagName = ref('');

const textareaRef = ref(null);

function autoResize() {
  const ta = textareaRef.value;
  if (ta) {
    ta.style.height = 'auto';
    ta.style.height = ta.scrollHeight + 'px';
  }
}

watch(editing, (val) => {
  if (val) {
    if (props.column.type === 'multiselect-relation') {
      loadMultiRelationOptions();
    }
    nextTick(() => {
      if (textareaRef.value) {
        autoResize();
        setTimeout(() => autoResize(), 0);
      }
    });
  }
});

// Добавляем watch для отслеживания изменений в мультисвязях с дебаунсингом
let debounceTimer = null;
watch(editMultiRelationValues, (newValues, oldValues) => {
      // console.log('[editMultiRelationValues] changed from:', oldValues, 'to:', newValues);
  
  // Очищаем предыдущий таймер
  if (debounceTimer) {
    clearTimeout(debounceTimer);
  }
  
  // Устанавливаем новый таймер для предотвращения множественных обновлений
  debounceTimer = setTimeout(() => {
    // Здесь можно добавить дополнительную логику, если нужно
  }, 100);
}, { deep: true });

// Флаг для предотвращения циклической загрузки
const isLoadingMultiRelations = ref(false);
const lastLoadedValues = ref(new Map()); // Кэш последних загруженных значений

// WebSocket для обновлений таблиц
const { subscribeToTableRelationsUpdates } = useTablesWebSocket();
let unsubscribeFromWebSocket = null;

// Функция для очистки кэша
function clearCache() {
  cacheService.clearAll();
      // console.log('[TableCell] Кэш очищен');
}

// WebSocket для тегов
const { onTagsUpdate } = useTagsWebSocket();
let unsubscribeFromTags = null;

// Удаляем локальные кэши
// const multiRelationOptionsCache = new Map();
// const multiRelationOptionsCacheTimeout = 30000; // 30 секунд
// const relationsCache = new Map();
// const relationsCacheTimeout = 10000; // 10 секунд

// Флаг для предотвращения повторных вызовов
let isInitialized = false;
let isMultiRelationValuesLoaded = false;
let lastLoadedOptionsKey = null;

onMounted(async () => {
  const startTime = Date.now();
      // console.log(`[TableCell] 🚀 Начало монтирования ячейки row:${props.rowId} col:${props.column.id} в ${startTime}`);
  
  if (props.column.type === 'multiselect') {
    multiOptions.value = (props.column.options && props.column.options.options) || [];
    const cell = props.cellValues.find(
      c => c.row_id === props.rowId && c.column_id === props.column.id
    );
    let values = [];
    if (cell && cell.value) {
      try {
        values = JSON.parse(cell.value);
      } catch {}
    }
    editMultiValues.value = Array.isArray(values) ? values : [];
    selectedMultiNames.value = multiOptions.value.filter(opt => editMultiValues.value.includes(opt));
  } else if (props.column.type === 'relation') {
    await loadRelationOptions();
    const cell = props.cellValues.find(
      c => c.row_id === props.rowId && c.column_id === props.column.id
    );
    editRelationValue.value = cell ? cell.value : null;
    selectedRelationName.value = relationOptions.value.find(opt => String(opt.id) === String(editRelationValue.value))?.display || '';
  } else if (props.column.type === 'lookup') {
    await loadLookupValues();
  } else if (props.column.type === 'multiselect-relation') {
    // Загружаем опции только один раз
    if (!isInitialized) {
      await loadMultiRelationOptions();
      isInitialized = true;
    }
    
    // Загружаем relations только один раз для каждой комбинации rowId + columnId
    if (!isMultiRelationValuesLoaded) {
      await loadMultiRelationValues();
      isMultiRelationValuesLoaded = true;
    }
    
    // Подписываемся на обновления таблицы
    if (props.column.type === 'multiselect-relation') {
      unsubscribeFromWebSocket = subscribeToTableRelationsUpdates(props.column.table_id, async () => {
        // console.log('[TableCell] Получено обновление таблицы, перезагружаем relations');
        // Сбрасываем флаг загрузки
        isMultiRelationValuesLoaded = false;
        // Очищаем кэш relations для текущей строки
        cacheService.clearRelationsCache(props.rowId);
        await loadMultiRelationValues();
      });
    }
    
    // Подписываемся на обновления тегов, если это связанная таблица тегов
    if (props.column.options && props.column.options.relatedTableId) {
      unsubscribeFromTags = onTagsUpdate(async () => {
        // console.log('[TableCell] Получено обновление тегов, перезагружаем опции');
        // Сбрасываем флаги загрузки
        isInitialized = false;
        isMultiRelationValuesLoaded = false;
        // Очищаем кэш таблицы тегов
        cacheService.clearTableCache(props.column.options.relatedTableId);
        await loadMultiRelationOptions();
        await loadMultiRelationValues();
      });
    }
    
    // Инициализация localValue для отображения массива, если нет имен
    const cell = props.cellValues.find(
      c => c.row_id === props.rowId && c.column_id === props.column.id
    );
    localValue.value = cell ? cell.value : '';
  } else {
    const cell = props.cellValues.find(
      c => c.row_id === props.rowId && c.column_id === props.column.id
    );
    localValue.value = cell ? cell.value : '';
  }
  const endTime = Date.now();
      // console.log(`[TableCell] ✅ Завершено монтирование ячейки row:${props.rowId} col:${props.column.id} за ${endTime - startTime}ms`);
});

onUnmounted(() => {
  // Отписываемся от WebSocket при размонтировании компонента
  if (unsubscribeFromWebSocket) {
    unsubscribeFromWebSocket();
    unsubscribeFromWebSocket = null;
  }
  
  // Отписываемся от обновлений тегов
  if (unsubscribeFromTags) {
    unsubscribeFromTags();
    unsubscribeFromTags = null;
  }
  
  // Очищаем таймер дебаунсинга
  if (loadMultiRelationValuesTimer) {
    clearTimeout(loadMultiRelationValuesTimer);
    loadMultiRelationValuesTimer = null;
  }
});

watch(
  () => [props.rowId, props.column.id, props.cellValues],
  async () => {
    // Сбрасываем флаги при изменении столбца
    if (props.column.type === 'multiselect-relation') {
      isMultiRelationValuesLoaded = false;
      lastLoadedOptionsKey = null;
      isInitialized = false;
    }
    if (props.column.type === 'multiselect') {
      multiOptions.value = (props.column.options && props.column.options.options) || [];
      const cell = props.cellValues.find(
        c => c.row_id === props.rowId && c.column_id === props.column.id
      );
      let values = [];
      if (cell && cell.value) {
        try {
          values = JSON.parse(cell.value);
        } catch {}
      }
      editMultiValues.value = Array.isArray(values) ? values : [];
      selectedMultiNames.value = multiOptions.value.filter(opt => editMultiValues.value.includes(opt));
    } else if (props.column.type === 'relation') {
      await loadRelationOptions();
      const cell = props.cellValues.find(
        c => c.row_id === props.rowId && c.column_id === props.column.id
      );
      editRelationValue.value = cell ? cell.value : null;
      selectedRelationName.value = relationOptions.value.find(opt => String(opt.id) === String(editRelationValue.value))?.display || '';
    } else if (props.column.type === 'lookup') {
      await loadLookupValues();
    } else if (props.column.type === 'multiselect-relation') {
      // Загружаем опции только один раз при изменении колонки
      await loadMultiRelationOptions();
      // Загружаем значения
      await loadMultiRelationValues();
      // Инициализация localValue для отображения массива, если нет имен
      const cell = props.cellValues.find(
        c => c.row_id === props.rowId && c.column_id === props.column.id
      );
      localValue.value = cell ? cell.value : '';
    } else {
      const cell = props.cellValues.find(
        c => c.row_id === props.rowId && c.column_id === props.column.id
      );
      localValue.value = cell ? cell.value : '';
    }
  },
  { immediate: true }
);

function saveMulti() {
  emit('update', JSON.stringify(editMultiValues.value));
  editing.value = false;
}
function cancelMulti() {
  editing.value = false;
  selectedMultiNames.value = multiOptions.value.filter(opt => editMultiValues.value.includes(opt));
}

async function addMultiOption() {
  const val = newMultiOption.value.trim();
  if (!val) return;
  // Если multiselect связан с relation-таблицей (например, Теги клиентов)
  if (props.column.options && props.column.options.relatedTableId && props.column.options.relatedColumnId) {
    // 1. Создаём строку в relation-таблице
    const newRow = await tablesService.addRow(props.column.options.relatedTableId);
    // 2. Сохраняем значение в нужную ячейку (название тега)
    await tablesService.saveCell({
      table_id: props.column.options.relatedTableId,
      row_id: newRow.id,
      column_id: props.column.options.relatedColumnId,
      value: val
    });
    // 3. Обновляем multiOptions (заново загружаем из relation-таблицы)
    const relTable = await tablesService.getTable(props.column.options.relatedTableId);
    const colId = props.column.options.relatedColumnId;
    multiOptions.value = relTable.rows.map(row => {
      const cell = relTable.cellValues.find(c => c.row_id === row.id && c.column_id === colId);
      return cell ? cell.value : `ID ${row.id}`;
    });
    // 4. Добавляем новый тег в выбранные
    editMultiValues.value.push(val);
    newMultiOption.value = '';
    return;
  }
  // Обычный multiselect (старый вариант)
  if (multiOptions.value.includes(val)) return;
  const updatedOptions = [...multiOptions.value, val];
  await updateMultiOptionsOnServer(updatedOptions);
  multiOptions.value = updatedOptions;
  newMultiOption.value = '';
}
async function removeMultiOption(option) {
  const updatedOptions = multiOptions.value.filter(o => o !== option);
  await updateMultiOptionsOnServer(updatedOptions);
  multiOptions.value = updatedOptions;
  // Если удалили выбранное — убираем из выбранных
  editMultiValues.value = editMultiValues.value.filter(v => v !== option);
}
async function updateMultiOptionsOnServer(optionsArr) {
  // PATCH /api/tables/column/:columnId
  const body = {
    options: {
      ...(props.column.options || {}),
      options: optionsArr
    }
  };
  await fetch(`/api/tables/column/${props.column.id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
  });
}

async function loadRelationOptions() {
  // Получаем данные из связанной таблицы (id и display)
  const opts = [];
  try {
    const rel = props.column.options || {};
    if (rel.relatedTableId) {
      const res = await fetch(`/api/tables/${rel.relatedTableId}`);
      const data = await res.json();
      const colId = rel.relatedColumnId || (data.columns[0] && data.columns[0].id);
      for (const row of data.rows) {
        const cell = data.cellValues.find(c => c.row_id === row.id && c.column_id === colId);
        opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
      }
    }
  } catch {}
  relationOptions.value = opts;
}
function saveRelation() {
  emit('update', editRelationValue.value);
  editing.value = false;
  selectedRelationName.value = relationOptions.value.find(opt => String(opt.id) === String(editRelationValue.value))?.display || '';
}
function cancelRelation() {
  editing.value = false;
}

async function loadLookupValues() {
  // Получаем связанные rowId через relation-таблицу
  lookupValues.value = [];
  try {
    const rel = props.column.options || {};
    if (rel.relatedTableId && rel.relatedColumnId) {
      // Получаем связи для текущей строки
      const res = await fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`);
      const relations = await res.json();
      // Фильтруем по нужному столбцу relation
      const relatedRowIds = relations
        .filter(r => String(r.column_id) === String(props.column.id) && String(r.to_table_id) === String(rel.relatedTableId))
        .map(r => r.to_row_id);
      if (relatedRowIds.length) {
        // Получаем значения из связанной таблицы
        const relTable = await fetch(`/api/tables/${rel.relatedTableId}`);
        const relData = await relTable.json();
        lookupValues.value = relatedRowIds.map(rowId => {
          const cell = relData.cellValues.find(c => c.row_id === rowId && c.column_id === rel.relatedColumnId);
          return cell ? cell.value : `ID ${rowId}`;
        });
      }
    }
  } catch {}
}

async function loadMultiRelationOptions() {
  // Проверяем, не загружены ли уже опции для текущего столбца
  const cacheKey = `${props.column.id}_${props.column.options?.relatedTableId}`;
  if (multiRelationOptions.value.length > 0 && lastLoadedOptionsKey === cacheKey) {
    return;
  }
  
  const rel = props.column.options || {};
  
  // Проверяем, что options содержат необходимые данные
  if (!rel.relatedTableId || !rel.relatedColumnId) {
    console.warn('[loadMultiRelationOptions] Отсутствуют relatedTableId или relatedColumnId в options:', rel);
    multiRelationOptions.value = [];
    selectedMultiRelationNames.value = [];
    return;
  }
  
  try {
    // Проверяем кэш для данных таблицы
    const cachedTableData = cacheService.getTableData(rel.relatedTableId, 'default');
    let tableData;
    
    if (cachedTableData) {
      console.log(`[loadMultiRelationOptions] ✅ Используем предварительно загруженные данные таблицы ${rel.relatedTableId}`);
      tableData = cachedTableData;
    } else {
      console.log(`[loadMultiRelationOptions] ⚠️ Данные таблицы ${rel.relatedTableId} не найдены в кэше, загружаем заново`);
      const response = await fetch(`/api/tables/${rel.relatedTableId}`);
      tableData = await response.json();
      // Сохраняем в кэш
      cacheService.setTableData(rel.relatedTableId, 'default', tableData);
    }
    
    // Формируем опции из данных таблицы
    const colId = rel.relatedColumnId || (tableData.columns[0] && tableData.columns[0].id);
    const opts = [];
    for (const row of tableData.rows) {
      const cell = tableData.cellValues.find(c => c.row_id === row.id && c.column_id === colId);
      opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
    }
    multiRelationOptions.value = opts;
    lastLoadedOptionsKey = cacheKey;
    
    console.log('[loadMultiRelationOptions] Загружено опций:', opts.length);
    
    // Обновляем selectedMultiRelationNames на основе текущих значений
    if (editMultiRelationValues.value.length > 0) {
      selectedMultiRelationNames.value = opts
        .filter(opt => editMultiRelationValues.value.includes(String(opt.id)))
        .map(opt => opt.display);
    } else {
      selectedMultiRelationNames.value = [];
    }
  } catch (e) {
    console.error('[loadMultiRelationOptions] Error:', e);
    multiRelationOptions.value = [];
    selectedMultiRelationNames.value = [];
  }
}

// Дебаунсинг для loadMultiRelationValues
let loadMultiRelationValuesTimer = null;
const LOAD_DEBOUNCE_DELAY = 50; // 50ms (уменьшено для ускорения)

async function loadMultiRelationValues() {
  // Проверяем, не загружены ли уже данные
  if (isMultiRelationValuesLoaded) {
    return;
  }
  
  // Очищаем предыдущий таймер
  if (loadMultiRelationValuesTimer) {
    clearTimeout(loadMultiRelationValuesTimer);
  }
  
  // Устанавливаем новый таймер
  loadMultiRelationValuesTimer = setTimeout(async () => {
    // Получаем связи для текущей строки
    // console.log('[loadMultiRelationValues] called for row:', props.rowId, 'column:', props.column.id);
    
    try {
      const rel = props.column.options || {};
      if (rel.relatedTableId && rel.relatedColumnId) {
        // Проверяем кэш для relations
        let relations;
        let tableData;
        
        const cachedRelations = cacheService.getRelationsData(props.rowId, props.column.id);
        if (cachedRelations) {
          // console.log('[loadMultiRelationValues] ✅ Используем предварительно загруженные relations для строки', props.rowId);
          relations = cachedRelations;
        } else {
          // console.log('[loadMultiRelationValues] ⚠️ Relations не найдены в кэше, загружаем заново для строки', props.rowId);
          // Выполняем запросы параллельно
          const [relationsRes, tableRes] = await Promise.all([
            fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`),
            fetch(`/api/tables/${rel.relatedTableId}`)
          ]);
          
          [relations, tableData] = await Promise.all([
            relationsRes.json(),
            tableRes.json()
          ]);
          
          // Сохраняем relations в кэш
          cacheService.setRelationsData(props.rowId, props.column.id, relations);
        }
        
        // console.log('[loadMultiRelationValues] API response status: 200 relations:', relations);
        
        // Приводим все id к строке для корректного сравнения
        const relatedRowIds = relations
          .filter(r => String(r.column_id) === String(props.column.id) && String(r.to_table_id) === String(rel.relatedTableId))
          .map(r => String(r.to_row_id));
        // console.log('[loadMultiRelationValues] filtered related row ids:', relatedRowIds);
        
        // Обновляем значения
        editMultiRelationValues.value = relatedRowIds;
        
        // Если tableData не загружена, загружаем её отдельно
        if (!tableData) {
          const tableRes = await fetch(`/api/tables/${rel.relatedTableId}`);
          tableData = await tableRes.json();
        }
        
        // Формируем опции из загруженных данных таблицы
        const colId = rel.relatedColumnId || (tableData.columns[0] && tableData.columns[0].id);
        const opts = [];
        for (const row of tableData.rows) {
          const cell = tableData.cellValues.find(c => c.row_id === row.id && c.column_id === colId);
          opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
        }
        multiRelationOptions.value = opts;
        
        // Получаем display-значения
        selectedMultiRelationNames.value = multiRelationOptions.value
          .filter(opt => relatedRowIds.includes(String(opt.id)))
          .map(opt => opt.display);
        
        // Отмечаем, что данные загружены
        isMultiRelationValuesLoaded = true;
      }
    } catch (e) {
      // console.error('[loadMultiRelationValues] Error:', e);
    }
  }, LOAD_DEBOUNCE_DELAY);
}

async function saveMultiRelation() {
  // console.log('[saveMultiRelation] called');
  const rel = props.column.options || {};
  // console.log('[saveMultiRelation] editMultiRelationValues:', editMultiRelationValues.value);
  try {
    const payload = {
      column_id: props.column.id,
      to_table_id: rel.relatedTableId,
      to_row_ids: editMultiRelationValues.value
    };
    // console.log('[saveMultiRelation] POST payload:', payload);
              // console.log('[TableCell] Отправляем запрос на обновление relations для строки:', props.rowId);
    // console.log('[TableCell] Данные запроса:', payload);
    const response = await fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });
    const result = await response.json().catch(() => ({}));
    // console.log('[TableCell] Ответ сервера для строки:', props.rowId, 'статус:', response.status, 'результат:', result);
    if (response.ok) {
      // console.log('[TableCell] Успешно сохранены теги для строки:', props.rowId);
    } else {
      // console.error('[TableCell] Ошибка сохранения тегов для строки:', props.rowId, 'статус:', response.status);
    }
    editing.value = false;
    await loadMultiRelationValues();
    // console.log('[saveMultiRelation] emitting update with:', editMultiRelationValues.value);
    emit('update', editMultiRelationValues.value);
  } catch (e) {
    // console.error('[saveMultiRelation] Ошибка при сохранении мультисвязи:', e);
  }
}

async function addTag() {
  if (!newTagName.value.trim()) return;
  const rel = props.column.options || {};
  
  try {
    // console.log('[addTag] Добавляем новый тег:', newTagName.value);
    
    // 1. Создаем новую пустую строку в связанной таблице
    const rowResponse = await fetch(`/api/tables/${rel.relatedTableId}/rows`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' }
    });
    const newRow = await rowResponse.json();
    
    // console.log('[addTag] Новая строка создана:', newRow);
    
    // 2. Добавляем значение в ячейку через POST /cell
    const cellResponse = await fetch(`/api/tables/cell`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        row_id: newRow.id,
        column_id: rel.relatedColumnId,
        value: newTagName.value
      })
    });
    const cellResult = await cellResponse.json();
    
    // console.log('[addTag] Значение ячейки сохранено:', cellResult);
    
    // Очищаем форму
    newTagName.value = '';
    showAddTagInput.value = false;
    
    // Обновляем список опций и добавляем тег в выбранные параллельно
    await Promise.all([
      loadMultiRelationOptions(),
      Promise.resolve(editMultiRelationValues.value.push(String(newRow.id)))
    ]);
    
    // console.log('[addTag] Тег добавлен в выбранные:', editMultiRelationValues.value);
    
    // Сохраняем изменения, чтобы отправить WebSocket уведомление
    await saveMultiRelation();
  } catch (e) {
    // console.error('[addTag] Ошибка при добавлении тега:', e);
  }
}

async function deleteTag(tagId) {
  const rel = props.column.options || {};
  if (!confirm('Удалить этот тег?')) return;
  
  try {
    // console.log('[deleteTag] Удаляем тег с ID:', tagId);
    
    // Удаляем тег из связанной таблицы
    const response = await fetch(`/api/tables/row/${tagId}`, { method: 'DELETE' });
    const result = await response.json();
    
    // console.log('[deleteTag] Ответ сервера:', response.status, result);
    
    // Убираем тег из выбранных значений, если он был выбран
    editMultiRelationValues.value = editMultiRelationValues.value.filter(id => String(id) !== String(tagId));
    
    // Обновляем список опций
    await loadMultiRelationOptions();
    
    // console.log('[deleteTag] Тег удален:', tagId);
    
    // Сохраняем изменения, чтобы отправить WebSocket уведомление
    await saveMultiRelation();
  } catch (e) {
    // console.error('[deleteTag] Ошибка при удалении тега:', e);
  }
}

function cancelMultiRelation() {
  // Сбрасываем форму добавления тега
  showAddTagInput.value = false;
  newTagName.value = '';
  
  // Закрываем режим редактирования
  editing.value = false;
  
  // Перезагружаем исходные значения
  loadMultiRelationValues();
}

function save() {
  emit('update', localValue.value);
}

function saveAndExit() {
  save();
  editing.value = false;
}

function isArrayString(val) {
  if (typeof val !== 'string') return false;
  try {
    const arr = JSON.parse(val);
    return Array.isArray(arr);
  } catch {
    return false;
  }
}
function parseArrayString(val) {
  if (typeof val !== 'string') return [];
  // Пробуем как JSON
  try {
    const arr = JSON.parse(val);
    if (Array.isArray(arr)) return arr.map(String);
  } catch {}
  // Пробуем как PostgreSQL-массив
  if (/^\{.*\}$/.test(val)) {
    return val.replace(/[{}\s"]/g, '').split(',').filter(Boolean);
  }
  // Если просто строка
  if (val.trim().length > 0) return [val.trim()];
  return [];
}

function prettyDisplay(val, optionsArr) {
  const arr = parseArrayString(val);
  if (!arr.length) return '—';
  if (optionsArr && Array.isArray(optionsArr)) {
    // Для relation/multiselect-relation ищу display по id
    return arr.map(id => {
      const found = optionsArr.find(opt => String(opt.id) === String(id) || String(opt) === String(id));
      return found ? (found.display || found) : id;
    }).join(', ');
  }
  return arr.join(', ');
}
</script>

<style scoped>
.cell-input {
  border: none !important;
  outline: none !important;
  background: transparent !important;
  box-shadow: none !important;
  padding: 0 !important;
  resize: none !important;
  width: 100% !important;
  min-height: 32px;
  font: inherit;
  color: inherit;
  overflow: hidden;
}
.cell-input:focus {
  border: 1.5px solid #2ecc40;
  outline: none;
}
.tags-cell-view, .tags-cell-edit, .lookup-cell-view, .tag-option, .multi-relation-option, .add-multiselect-option, .add-tag-form, .multi-relation-options, .multi-relation-edit, .multi-relation-actions, .action-buttons {
  white-space: normal !important;
  word-break: break-word !important;
  height: auto !important;
  min-height: 1.7em;
  align-items: flex-start !important;
  vertical-align: top !important;
  overflow: visible !important;
}
.tags-cell-view {
  min-height: 1.7em;
  cursor: pointer;
  padding: 0.2em 0.1em;
}
.tags-cell-edit {
  background: #f8f8f8;
  border-radius: 6px;
  padding: 0.3em 0.2em 0.5em 0.2em;
}
.tags-multiselect {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em 1.2em;
  margin-bottom: 0.7em;
}
.tag-option {
  display: flex;
  align-items: center;
  gap: 0.3em;
}
.save-btn {
  background: #2ecc40;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 0.3em 1em;
  font-weight: 600;
  cursor: pointer;
  margin-right: 0.7em;
  transition: background 0.2s;
}
.save-btn:hover {
  background: #27ae38;
}
.cancel-btn {
  background: #eaeaea;
  color: #333;
  border: none;
  border-radius: 8px;
  padding: 0.3em 1em;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.2s;
}
.cancel-btn:hover {
  background: #d5d5d5;
}
.add-multiselect-option {
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin-bottom: 0.7em;
}
.add-multiselect-option input {
  flex: 1;
  padding: 0.2em 0.5em;
  border: 1px solid #e0e0e0;
  border-radius: 5px;
  font-size: 1em;
}
.add-btn {
  background: #2ecc40;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 0.3em 1em;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}
.add-btn:hover {
  background: #27ae38;
}
.remove-option {
  color: #e74c3c;
  font-size: 1.1em;
  margin-left: 0.4em;
  cursor: pointer;
  user-select: none;
  transition: color 0.2s;
}
.remove-option:hover {
  color: #c0392b;
}
.lookup-cell-view {
  min-height: 1.7em;
  padding: 0.2em 0.1em;
  color: #222;
}
.multi-relation-edit {
  padding: 8px 0;
}
.multi-relation-options {
  max-height: 180px;
  overflow-y: auto;
  margin-bottom: 8px;
}
.multi-relation-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 0;
}
.delete-tag-btn {
  background: none;
  border: none;
  color: #e53e3e;
  font-size: 1.1em;
  cursor: pointer;
  padding: 0 4px;
}
.multi-relation-actions {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}
.save-btn {
  background: #4f8cff;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 4px 12px;
  cursor: pointer;
}
.cancel-btn {
  background: #f3f4f6;
  color: #333;
  border: none;
  border-radius: 4px;
  padding: 4px 12px;
  cursor: pointer;
}
.add-tag-block {
  margin-top: 8px;
}
.add-tag-btn {
  background: #f3f4f6;
  color: #4f8cff;
  border: none;
  border-radius: 4px;
  padding: 4px 10px;
  cursor: pointer;
}
.add-tag-form {
  display: flex;
  gap: 6px;
  align-items: center;
}
.add-tag-form input {
  padding: 3px 8px;
  border: 1px solid #d1d5db;
  border-radius: 4px;
}
.add-tag-confirm {
  background: #4f8cff;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 3px 10px;
  cursor: pointer;
}
.add-tag-cancel {
  background: none;
  border: none;
  color: #e53e3e;
  font-size: 1.1em;
  cursor: pointer;
  padding: 0 4px;
}

.action-buttons {
  display: flex;
  gap: 0.5em;
  margin-top: 0.7em;
}

.delete-tag-btn:hover {
  color: #c0392b;
}

.add-tag-btn:hover {
  background: #e2e8f0;
  color: #3182ce;
}

.add-tag-confirm:hover {
  background: #3182ce;
}

.add-tag-block {
  margin: 0.7em 0;
}
.cell-view-value {
  display: block;
  white-space: pre-wrap !important;
  word-break: break-word !important;
  overflow-wrap: anywhere !important;
  width: 100%;
  cursor: pointer;
  transition: background 0.15s;
  min-height: 32px;
}
.cell-view-value:hover {
  background: #f3f4f6;
}
.cell-plus-icon {
  color: #b6c6e6;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2em;
  transition: color 0.15s;
  vertical-align: middle;
}
.cell-plus-icon:hover {
  color: #4f8cff;
}
</style> 