<script lang="ts" setup>
/**
 * 金方「药方设置」弹窗
 * 独立编辑药方组成（name/dose/unit/usage/ancient_dose/prep），并标红本方缺失药名
 */
import { computed, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';

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

import {
  getGoldenFormulaDrugsDetail,
  updateGoldenFormulaDrugs,
} from '../api';
import ResolveMissingDrugPanel from './ResolveMissingDrugPanel.vue';

/** 单味药编辑行 */
interface DrugRow {
  key: string;
  name: string;
  dose: string;
  unit: string;
  usage: string;
  ancient_dose: string;
  prep: string;
  /** 替换已有药时保留的旧药名 */
  origin_name: string;
}

const formulaId = ref(0);
const formulaName = ref('');
const drugRows = ref<DrugRow[]>([]);
const missingSet = ref<Set<string>>(new Set());
const loading = ref(false);
const gridApi = ref();
let rowKeySeq = 0;

/** 缺失药处理面板 */
const resolveOpen = ref(false);
const resolveDrugName = ref('');

/** 本方缺失药味数（按当前编辑行实时统计） */
const missingCount = computed(() => {
  let n = 0;
  for (const row of drugRows.value) {
    const name = String(row.name || '').trim();
    if (name && missingSet.value.has(name)) n += 1;
  }
  return n;
});

const columns = [
  { title: '药名', dataIndex: 'name', key: 'name', width: 130 },
  { title: '旧名', dataIndex: 'origin_name', key: 'origin_name', width: 100 },
  { title: '剂量(克)', dataIndex: 'dose', key: 'dose', width: 90 },
  { title: '单位', dataIndex: 'unit', key: 'unit', width: 70 },
  { title: '煎法', dataIndex: 'usage', key: 'usage', width: 100 },
  { title: '古代剂量', dataIndex: 'ancient_dose', key: 'ancient_dose', width: 100 },
  { title: '炮制', dataIndex: 'prep', key: 'prep', width: 90 },
  { title: '操作', key: 'action', width: 140, fixed: 'right' as const },
];

const [Modal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  class: 'w-[960px]',
  onCancel() {
    modalApi.close();
  },
  onConfirm: async () => {
    if (formulaId.value <= 0) {
      message.warning('金方无效');
      return;
    }
    // 过滤空药名行；至少允许空组成（异常方运营可后补）
    const drugs_json = drugRows.value
      .map((r) => {
        const row: Record<string, string> = {
          name: String(r.name || '').trim(),
          dose: String(r.dose || '').trim(),
          unit: String(r.unit || '').trim() || 'g',
          usage: String(r.usage || '').trim(),
          ancient_dose: String(r.ancient_dose || '').trim(),
          prep: String(r.prep || '').trim(),
        };
        const origin = String(r.origin_name || '').trim();
        if (origin) {
          row.origin_name = origin;
        }
        return row;
      })
      .filter((r) => r.name !== '');
    modalApi.setState({ confirmLoading: true });
    try {
      await updateGoldenFormulaDrugs({
        id: formulaId.value,
        drugs_json,
      });
      message.success('药方设置已保存');
      gridApi.value?.query?.();
      gridApi.value?.reload?.();
      modalApi.close();
    } catch (e: any) {
      message.error(e?.message || '保存失败');
    } finally {
      modalApi.setState({ confirmLoading: false });
    }
  },
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formulaId.value = 0;
      formulaName.value = '';
      drugRows.value = [];
      missingSet.value = new Set();
      gridApi.value = null;
      resolveOpen.value = false;
      resolveDrugName.value = '';
      return;
    }
    const data = modalApi.getData<{ id?: number; gridApi?: any }>() || {};
    gridApi.value = data.gridApi || null;
    const id = Number(data.id || 0);
    if (id <= 0) {
      message.error('缺少金方 ID');
      modalApi.close();
      return;
    }
    formulaId.value = id;
    await loadDetail(id);
  },
});

/**
 * 拉取药方组成详情，并建立缺失药名集合
 */
async function loadDetail(id: number) {
  loading.value = true;
  try {
    const res = await getGoldenFormulaDrugsDetail(id);
    formulaName.value = String(res?.name || '');
    const missing = Array.isArray(res?.missing) ? res.missing : [];
    missingSet.value = new Set(missing.map((n: string) => String(n).trim()).filter(Boolean));
    const raw = Array.isArray(res?.drugs_json) ? res.drugs_json : [];
    // 关联对象含 error 时无法拆成药味行，给空表让运营重填
    if (raw.length === 0 || (raw as any).error || !Array.isArray(raw)) {
      const asObj = res?.drugs_json;
      if (asObj && typeof asObj === 'object' && !Array.isArray(asObj) && (asObj as any).error) {
        drugRows.value = [];
        return;
      }
    }
    drugRows.value = (Array.isArray(raw) ? raw : []).map((item: any) =>
      toDrugRow(item),
    );
    if (drugRows.value.length === 0) {
      addRow();
    }
  } catch (e: any) {
    message.error(e?.message || '加载药方组成失败');
    drugRows.value = [];
  } finally {
    loading.value = false;
  }
}

/** 后端一行转为可编辑行 */
function toDrugRow(item: any): DrugRow {
  rowKeySeq += 1;
  return {
    key: `d-${rowKeySeq}`,
    name: String(item?.name || item?.drug_name || ''),
    dose: String(item?.dose ?? ''),
    unit: String(item?.unit || 'g'),
    usage: String(item?.usage || ''),
    ancient_dose: String(item?.ancient_dose || ''),
    prep: String(item?.prep || ''),
    origin_name: String(item?.origin_name || item?.old_name || ''),
  };
}

/** 新增一味空药 */
function addRow() {
  rowKeySeq += 1;
  drugRows.value.push({
    key: `d-${rowKeySeq}`,
    name: '',
    dose: '',
    unit: 'g',
    usage: '',
    ancient_dose: '',
    prep: '',
    origin_name: '',
  });
}

/** 删除一行 */
function removeRow(key: string) {
  drugRows.value = drugRows.value.filter((r) => r.key !== key);
}

/**
 * 打开缺失药处理：添加药材 / 挂别名
 */
function openResolve(name: string) {
  const n = String(name || '').trim();
  if (!n || !missingSet.value.has(n)) {
    return;
  }
  resolveDrugName.value = n;
  resolveOpen.value = true;
}

/**
 * 处理完成后重新拉取组成（替换会改 name/origin_name，需整表回填）
 */
async function onResolveDone() {
  if (formulaId.value <= 0) return;
  try {
    await loadDetail(formulaId.value);
    gridApi.value?.query?.();
  } catch {
    // 刷新失败不阻塞
  }
}
</script>
<template>
  <Modal :title="`药方设置${formulaName ? ` · ${formulaName}` : ''}`">
    <div class="gf-drugs-toolbar">
      <div class="gf-drugs-summary">
        <span>共 {{ drugRows.length }} 行</span>
        <Tag v-if="missingCount > 0" color="error">
          本方缺失 {{ missingCount }} 味（红字可点「处理」）
        </Tag>
        <Tag v-else color="success">本方药名均已匹配</Tag>
      </div>
      <Button type="dashed" size="small" @click="addRow">添加药味</Button>
    </div>
    <Table
      :columns="columns"
      :data-source="drugRows"
      :loading="loading"
      :pagination="false"
      row-key="key"
      size="small"
      bordered
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'name'">
          <Input
            v-model:value="record.name"
            :class="{ 'gf-drug-missing': missingSet.has(String(record.name || '').trim()) }"
            placeholder="药名"
            allow-clear
          />
        </template>
        <template v-else-if="column.key === 'origin_name'">
          <span class="gf-origin-name">{{ record.origin_name || '—' }}</span>
        </template>
        <template v-else-if="column.key === 'dose'">
          <Input v-model:value="record.dose" placeholder="克数" allow-clear />
        </template>
        <template v-else-if="column.key === 'unit'">
          <Input v-model:value="record.unit" placeholder="g" allow-clear />
        </template>
        <template v-else-if="column.key === 'usage'">
          <Input v-model:value="record.usage" placeholder="先煎/后下" allow-clear />
        </template>
        <template v-else-if="column.key === 'ancient_dose'">
          <Input v-model:value="record.ancient_dose" placeholder="三两" allow-clear />
        </template>
        <template v-else-if="column.key === 'prep'">
          <Input v-model:value="record.prep" placeholder="去皮/炙" allow-clear />
        </template>
        <template v-else-if="column.key === 'action'">
          <Space :size="0">
            <Button
              v-if="missingSet.has(String(record.name || '').trim())"
              type="link"
              size="small"
              @click="openResolve(record.name)"
            >
              处理
            </Button>
            <Button type="link" danger size="small" @click="removeRow(record.key)">
              删除
            </Button>
          </Space>
        </template>
      </template>
    </Table>
    <ResolveMissingDrugPanel
      v-model:open="resolveOpen"
      :drug-name="resolveDrugName"
      :formula-id="formulaId"
      @done="onResolveDone"
    />
  </Modal>
</template>
<style scoped>
.gf-drugs-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  gap: 12px;
}
.gf-drugs-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  color: hsl(var(--muted-foreground));
  font-size: 13px;
}
.gf-origin-name {
  color: hsl(var(--muted-foreground));
  font-size: 12px;
}
/* 缺失药名输入框：用 destructive 强调，暗色可读 */
:deep(.gf-drug-missing) {
  color: hsl(var(--destructive));
  font-weight: 600;
}
:deep(.gf-drug-missing input) {
  color: hsl(var(--destructive));
  font-weight: 600;
}
</style>
