<script lang="ts" setup>
import type { SpreadsheetHeaderConfig } from '#/components/canvas-spreadsheet';

import { computed, onMounted, ref, watch } from 'vue';

import {
  Button,
  Checkbox,
  Input,
  message,
  Popover,
  Select,
  Space,
  Tag,
} from 'ant-design-vue';

import {
  buildFormulaFromTemplate,
  listSpreadsheetFormula,
  type SpreadsheetFormulaItem,
} from '#/api/spreadsheet-formula';
import { colIndexToLetters } from '#/components/canvas-spreadsheet';

const props = withDefaults(
  defineProps<{
    modelValue: string;
    headers: SpreadsheetHeaderConfig[];
    disabled?: boolean;
    compact?: boolean;
    isDark?: boolean;
    showPreview?: boolean;
  }>(),
  {
    disabled: false,
    compact: false,
    isDark: false,
    showPreview: true,
  },
);

const emit = defineEmits<{
  'update:modelValue': [value: string];
}>();

const pickerOpen = ref(false);
const useCustomFormula = ref(false);
const customFormula = ref('');
const selectedFormulaId = ref<number | null>(null);
const refColumns = ref<number[]>([]);
const refPopoverOpen = ref(false);
const formulas = ref<SpreadsheetFormulaItem[]>([]);

const formulaOptions = computed(() =>
  formulas.value.map((f) => ({ label: f.name, value: f.id })),
);

const selectedFormula = computed(() =>
  formulas.value.find((f) => f.id === selectedFormulaId.value),
);

const columnChoices = computed(() =>
  props.headers.map((h) => ({
    col: h.col,
    label: `${colIndexToLetters(h.col)} · ${h.title}`,
  })),
);

const previewFormula = computed(() => {
  if (useCustomFormula.value) return customFormula.value;
  const tpl = selectedFormula.value?.expression_template ?? '';
  if (!tpl) return props.modelValue;
  if (refColumns.value.length === 0) return tpl;
  return buildFormulaFromTemplate(tpl, refColumns.value);
});

function syncFromModelValue() {
  if (props.modelValue?.trim()) {
    useCustomFormula.value = true;
    customFormula.value = props.modelValue;
  }
}

async function loadFormulas() {
  try {
    formulas.value = await listSpreadsheetFormula();
  } catch {
    formulas.value = [];
  }
}

function toggleRefCol(col: number, checked: boolean) {
  const slots = selectedFormula.value?.ref_slots?.length ?? 2;
  if (checked) {
    if (refColumns.value.length >= slots) {
      message.warning(`最多选择 ${slots} 列`);
      return;
    }
    refColumns.value = [...refColumns.value, col];
  } else {
    refColumns.value = refColumns.value.filter((c) => c !== col);
  }
}

function applyFormula() {
  const next = previewFormula.value.trim();
  if (!next) {
    message.warning('请选择公式或输入表达式');
    return;
  }
  emit('update:modelValue', next);
  pickerOpen.value = false;
}

function onCustomInput(v: string) {
  customFormula.value = v;
  emit('update:modelValue', v);
}

onMounted(() => {
  void loadFormulas();
  syncFromModelValue();
});

watch(
  () => props.modelValue,
  (v) => {
    if (useCustomFormula.value && v !== customFormula.value) {
      customFormula.value = v;
    }
  },
);

watch(pickerOpen, (open) => {
  if (open) {
    void loadFormulas();
    if (props.modelValue?.trim()) {
      useCustomFormula.value = true;
      customFormula.value = props.modelValue;
    }
  }
});

watch(previewFormula, (v) => {
  if (!props.compact && !useCustomFormula.value && v) {
    emit('update:modelValue', v);
  }
});
</script>

<template>
  <div class="spreadsheet-formula-field" :class="{ compact, 'is-dark': isDark }">
    <template v-if="compact">
      <Input
        :disabled="disabled"
        :value="modelValue"
        placeholder="=(D1-E1)"
        size="small"
        @update:value="onCustomInput"
      />
      <Popover
        v-model:open="pickerOpen"
        placement="bottomLeft"
        trigger="click"
        :overlay-class-name="
          isDark
            ? 'sheet-formula-field-popover is-dark'
            : 'sheet-formula-field-popover'
        "
      >
        <template #content>
          <div class="picker-panel" :class="{ 'is-dark': isDark }">
            <Space direction="vertical" style="width: 280px">
              <Checkbox
                v-model:checked="useCustomFormula"
                :disabled="disabled"
              >
                手写公式
              </Checkbox>
              <template v-if="useCustomFormula">
                <Input
                  v-model:value="customFormula"
                  :disabled="disabled"
                  placeholder="=(E1-D1)/D1"
                  @update:value="onCustomInput"
                />
              </template>
              <template v-else>
                <Select
                  v-model:value="selectedFormulaId"
                  :disabled="disabled"
                  :options="formulaOptions"
                  allow-clear
                  placeholder="选择公式模板"
                  style="width: 100%"
                />
                <div v-if="selectedFormula">
                  <div class="field-label">引用列（按顺序）</div>
                  <Popover v-model:open="refPopoverOpen" trigger="click">
                    <template #content>
                      <div class="ref-picker">
                        <div
                          v-for="item in columnChoices"
                          :key="item.col"
                          class="ref-item"
                        >
                          <Checkbox
                            :checked="refColumns.includes(item.col)"
                            @change="
                              (e) => toggleRefCol(item.col, !!e.target.checked)
                            "
                          >
                            {{ item.label }}
                          </Checkbox>
                        </div>
                      </div>
                    </template>
                    <Input
                      readonly
                      :disabled="disabled"
                      placeholder="点击选择引用列"
                      size="small"
                      :value="
                        refColumns.map((c) => colIndexToLetters(c)).join(', ')
                      "
                    />
                  </Popover>
                </div>
              </template>
              <div v-if="showPreview">
                <div class="field-label">预览</div>
                <Tag color="blue">{{ previewFormula || '—' }}</Tag>
              </div>
              <Button
                block
                :disabled="disabled"
                size="small"
                type="primary"
                @click="applyFormula"
              >
                应用
              </Button>
            </Space>
          </div>
        </template>
        <Button
          class="fx-btn"
          :disabled="disabled"
          size="small"
          type="text"
          @click.stop
        >
          fx
        </Button>
      </Popover>
    </template>

    <template v-else>
      <Checkbox v-model:checked="useCustomFormula" :disabled="disabled">
        手写公式
      </Checkbox>
      <template v-if="useCustomFormula">
        <Input
          v-model:value="customFormula"
          :disabled="disabled"
          placeholder="=(E1-D1)/D1"
          @update:value="onCustomInput"
        />
      </template>
      <template v-else>
        <Select
          v-model:value="selectedFormulaId"
          :disabled="disabled"
          :options="formulaOptions"
          allow-clear
          placeholder="选择公式模板"
          style="width: 100%"
        />
        <div v-if="selectedFormula">
          <div class="field-label">引用列（按顺序）</div>
          <Popover v-model:open="refPopoverOpen" trigger="click">
            <template #content>
              <div class="ref-picker">
                <div
                  v-for="item in columnChoices"
                  :key="item.col"
                  class="ref-item"
                >
                  <Checkbox
                    :checked="refColumns.includes(item.col)"
                    @change="
                      (e) => toggleRefCol(item.col, !!e.target.checked)
                    "
                  >
                    {{ item.label }}
                  </Checkbox>
                </div>
              </div>
            </template>
            <Input
              readonly
              :disabled="disabled"
              placeholder="点击选择引用列"
              :value="refColumns.map((c) => colIndexToLetters(c)).join(', ')"
            />
          </Popover>
          <div v-if="selectedFormula.ref_slots?.length" class="ref-hint">
            需要：
            {{ selectedFormula.ref_slots.map((s) => s.label).join('、') }}
          </div>
        </div>
      </template>
      <div v-if="showPreview">
        <div class="field-label">公式预览</div>
        <Tag color="blue">{{ previewFormula || '—' }}</Tag>
      </div>
    </template>
  </div>
</template>

<style scoped lang="scss">
.spreadsheet-formula-field {
  &.compact {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 100%;

    :deep(.ant-input) {
      flex: 1;
      min-width: 0;
    }
  }
}

.fx-btn {
  font-style: italic;
  font-weight: 600;
  color: #1668dc;
  flex-shrink: 0;
}

.field-label {
  font-size: 12px;
  color: #86909c;
  margin-bottom: 4px;
}

.ref-picker {
  width: 260px;
  max-height: 240px;
  overflow: auto;
}

.ref-item {
  padding: 4px 0;
}

.ref-hint {
  font-size: 12px;
  color: #86909c;
  margin-top: 4px;
}

.picker-panel {
  padding: 4px;

  &.is-dark {
    .field-label,
    .ref-hint {
      color: rgba(255, 255, 255, 0.45);
    }
  }
}

.is-dark .fx-btn {
  color: #3c89e8;
}
</style>

<style lang="scss">
.sheet-formula-field-popover.is-dark {
  .ant-popover-inner {
    background: #1f1f1f;
    border: 1px solid #424242;
  }
}
</style>
