import type { QualityComponentDefinition } from '../core/types';

import { QUALITY_REPEAT_ATTR, QUALITY_REPEAT_ROW_ATTR } from '../core/attrs';
import { cssStyle, escapeHtml } from '../core/html';
import { QUALITY_ICONS } from '../core/icons';
import { QUALITY_CATEGORY } from '../core/types';

/** 检验项数组在报告上下文中的默认路径 */
const DEFAULT_ITEMS_PATH = 'inspectionItems';

/** 循环变量名，行内占位符写作 {{item.xxx}} */
const LOOP_VAR = 'item';

/** 渲染期由重复容器注入的行号变量，写作 {{index}}，从 1 开始 */
const INDEX_VAR = 'index';

const CELL_BORDER = '1px solid #d9d9d9';

interface ColumnSpec {
  /** 表头文字 */
  label: string;
  /** 行内取值表达式 */
  expr: string;
  /** 对应的显示开关属性名 */
  toggle: string;
  width?: string;
}

const COLUMNS: ColumnSpec[] = [
  { label: '序号', expr: `{{${INDEX_VAR}}}`, toggle: 'showIndex', width: '48px' },
  { label: '检验项目', expr: `{{${LOOP_VAR}.itemName}}`, toggle: '' },
  { label: '标准值', expr: `{{${LOOP_VAR}.standardValue}}`, toggle: 'showStandard' },
  { label: '实测值', expr: `{{${LOOP_VAR}.actualValue}}`, toggle: 'showActual', width: '40%' },
  { label: '单位', expr: `{{${LOOP_VAR}.unit}}`, toggle: 'showUnit', width: '60px' },
  { label: '判定', expr: `{{${LOOP_VAR}.resultText}}`, toggle: 'showResult', width: '72px' },
];

export const qualityTableDefinition: QualityComponentDefinition = {
  type: 'QualityTable',
  name: 'qualityTable',
  label: '检验项目表格',
  category: QUALITY_CATEGORY.INSPECTION,
  icon: QUALITY_ICONS.qualityTable,
  aiHint:
    '多行检验数据的表格，检验项平铺一层、没有父子关系（序号/检验项目/标准值/实测值/单位/判定）。' +
    '一个检验项目下挂若干子项（原件里表现为该列纵向合并、后续行写着「↑同上」）时不要用我，' +
    '改用分组检验项表。' +
    '报告末尾的落款签署行（检验员/审核人/日期）不要放进我这里，那属于 ReportFooter。',
  defaults: {
    title: '检验项目',
    itemsPath: DEFAULT_ITEMS_PATH,
    showIndex: true,
    showStandard: true,
    showActual: true,
    showUnit: true,
    showResult: true,
  },
  propertySchema: [
    { key: 'title', label: '表格标题', type: 'string', defaultValue: '检验项目' },
    {
      key: 'itemsPath',
      label: '检验项数据源',
      type: 'string',
      defaultValue: DEFAULT_ITEMS_PATH,
      required: true,
      bindable: true,
      // 渲染期按这个路径取数组逐行生成，必须是裸路径，不能写成 {{...}}
      bindAs: 'path',
      tip: '报告上下文中检验项目数组的路径，渲染时按它逐行生成',
    },
    { key: 'showIndex', label: '显示序号', type: 'boolean', defaultValue: true },
    { key: 'showStandard', label: '显示标准值', type: 'boolean', defaultValue: true },
    { key: 'showActual', label: '显示实测值', type: 'boolean', defaultValue: true },
    { key: 'showUnit', label: '显示单位', type: 'boolean', defaultValue: true },
    { key: 'showResult', label: '显示判定', type: 'boolean', defaultValue: true },
  ],
  dataSchema: [
    { key: DEFAULT_ITEMS_PATH, label: '检验项目列表', type: 'string', bindable: true },
    { key: INDEX_VAR, label: '行序号', type: 'number', bindable: true },
    { key: `${LOOP_VAR}.itemName`, label: '检验项目名称', type: 'string', bindable: true },
    { key: `${LOOP_VAR}.standardValue`, label: '标准值', type: 'string', bindable: true },
    { key: `${LOOP_VAR}.actualValue`, label: '实测值', type: 'string', bindable: true },
    { key: `${LOOP_VAR}.unit`, label: '单位', type: 'string', bindable: true },
    { key: `${LOOP_VAR}.resultText`, label: '判定结果', type: 'string', bindable: true },
  ],
  buildContent: (properties) => {
    const visible = COLUMNS.filter(
      (column) => column.toggle === '' || properties[column.toggle] !== false,
    );
    const head = visible
      .map(
        (column) =>
          `<th style="${cssStyle({
            border: CELL_BORDER,
            padding: '6px 8px',
            background: '#fafafa',
            'font-weight': 600,
            width: column.width,
          })}">${column.label}</th>`,
      )
      .join('');
    const row = visible
      .map(
        (column) =>
          `<td style="${cssStyle({ border: CELL_BORDER, padding: '6px 8px' })}">${column.expr}</td>`,
      )
      .join('');
    const rawTitle = String(properties.title ?? '').trim();
    const heading = rawTitle
      ? `<div style="${cssStyle({ 'font-size': '13px', 'font-weight': 600, margin: '0 0 4px' })}">${escapeHtml(rawTitle)}</div>`
      : '';
    const itemsPath = String(properties.itemsPath ?? DEFAULT_ITEMS_PATH).trim() || DEFAULT_ITEMS_PATH;
    const table =
      `<table style="${cssStyle({ width: '100%', 'border-collapse': 'collapse', 'font-size': '12px' })}">` +
      `<thead><tr>${head}</tr></thead>` +
      // 渲染期按 data-qc-repeat 指向的数组复制 data-qc-repeat-row 所在的行
      `<tbody ${QUALITY_REPEAT_ATTR}="${escapeHtml(itemsPath)}">` +
      `<tr ${QUALITY_REPEAT_ROW_ATTR}="${LOOP_VAR}">${row}</tr>` +
      `</tbody></table>`;
    return {
      tagName: 'div',
      components: heading + table,
      style: { margin: '0 0 10px' },
    };
  },
  validate: (properties) => {
    const path = String(properties.itemsPath ?? '').trim();
    const errors: string[] = [];
    if (!path) {
      errors.push('检验项目表格的「检验项数据源」不能为空，渲染时无法确定生成哪些行');
    }
    if (properties.showStandard === false && properties.showResult === true) {
      errors.push(
        '检验项目表格隐藏了「标准值」却保留「判定」列，判定依据将不可见，请一并隐藏判定或恢复标准值',
      );
    }
    return errors;
  },
};