<template>
  <section class="panel">
    <div class="panel-toolbar">
      <div class="handoff-summary" aria-label="现场联调进度">
        <span>总项 <strong>{{ checklist.length }}</strong></span>
        <span>通过 <strong>{{ passedCount }}</strong></span>
        <span>阻断 <strong>{{ blockedCount }}</strong></span>
        <span>待处理 <strong>{{ pendingCount }}</strong></span>
      </div>
      <div class="toolbar-actions">
        <el-segmented v-model="category" :options="categoryOptions" />
        <el-select v-model="statusFilter" class="handoff-status-select" placeholder="状态">
          <el-option label="全部状态" value="ALL" />
          <el-option label="待处理" value="PENDING" />
          <el-option label="通过" value="PASS" />
          <el-option label="阻断" value="BLOCKED" />
          <el-option label="不适用" value="SKIP" />
        </el-select>
        <el-popover trigger="click" width="360">
          <template #reference>
            <el-button :icon="ListChecks" :disabled="filteredChecklist.length === 0">
              批量标记
            </el-button>
          </template>
          <el-form class="handoff-bulk-form" label-position="top">
            <el-alert
              :title="`将更新当前筛选出的 ${filteredChecklist.length} 个检查项`"
              type="info"
              show-icon
              :closable="false"
            />
            <el-form-item label="状态">
              <el-select v-model="bulkForm.status">
                <el-option label="待处理" value="PENDING" />
                <el-option label="通过" value="PASS" />
                <el-option label="阻断" value="BLOCKED" />
                <el-option label="不适用" value="SKIP" />
              </el-select>
            </el-form-item>
            <el-form-item label="负责人">
              <el-input v-model="bulkForm.owner" placeholder="留空则不覆盖" />
            </el-form-item>
            <el-form-item label="结果记录">
              <el-input v-model="bulkForm.note" placeholder="留空则不覆盖" />
            </el-form-item>
            <el-button type="primary" :icon="Check" @click="applyBulkMark">应用到当前筛选</el-button>
          </el-form>
        </el-popover>
        <el-button :icon="Download" @click="exportChecklist">导出</el-button>
        <el-button :icon="RotateCcw" @click="resetDraft">重置</el-button>
      </div>
    </div>

    <div class="handoff-body">
      <el-alert
        title="仅记录现场联调准备和执行结果，不替代微信商户、合法域名或硬件实测验收。"
        type="warning"
        show-icon
        :closable="false"
      />
      <section class="handoff-session">
        <el-form label-position="top">
          <el-form-item label="联调批次">
            <el-input
              v-model="sessionMeta.batchNo"
              placeholder="例如 2026-07-现场一轮"
              @change="persistSessionMeta"
            />
          </el-form-item>
          <el-form-item label="现场/门店">
            <el-input
              v-model="sessionMeta.site"
              placeholder="门店或现场位置"
              @change="persistSessionMeta"
            />
          </el-form-item>
          <el-form-item label="负责人">
            <el-input
              v-model="sessionMeta.coordinator"
              placeholder="现场负责人"
              @change="persistSessionMeta"
            />
          </el-form-item>
          <el-form-item label="执行时间">
            <el-input
              v-model="sessionMeta.executedAt"
              placeholder="YYYY-MM-DD HH:mm"
              @change="persistSessionMeta"
            />
          </el-form-item>
        </el-form>
      </section>
      <section v-if="blockedItems.length" class="handoff-blockers">
        <header>
          <div>
            <h3>阻断摘要</h3>
            <span>{{ blockedItems.length }} 个现场阻断项需要外部处理</span>
          </div>
          <el-button :icon="Copy" @click="copyBlockedSummary">复制摘要</el-button>
        </header>
        <ul>
          <li v-for="item in blockedItems" :key="item.id">
            <strong>{{ item.category }} · {{ item.title }}</strong>
            <span>{{ draft[item.id].owner || '未分派' }} / {{ draft[item.id].note || item.expected }}</span>
          </li>
        </ul>
      </section>

      <el-table :data="filteredChecklist" class="data-table" row-key="id">
        <el-table-column prop="category" label="类别" width="120" />
        <el-table-column prop="title" label="检查项" min-width="210">
          <template #default="{ row }">
            <div class="stack">
              <strong>{{ row.title }}</strong>
              <span>{{ row.expected }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="状态" width="150">
          <template #default="{ row }">
            <el-select
              v-model="draft[row.id].status"
              size="small"
              @change="persistDraft"
            >
              <el-option label="待处理" value="PENDING" />
              <el-option label="通过" value="PASS" />
              <el-option label="阻断" value="BLOCKED" />
              <el-option label="不适用" value="SKIP" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column label="负责人" width="150">
          <template #default="{ row }">
            <el-input
              v-model="draft[row.id].owner"
              size="small"
              placeholder="负责人"
              @change="persistDraft"
            />
          </template>
        </el-table-column>
        <el-table-column label="结果记录" min-width="230">
          <template #default="{ row }">
            <el-input
              v-model="draft[row.id].note"
              size="small"
              placeholder="时间、流水、设备ID或阻断原因"
              @change="persistDraft"
            />
          </template>
        </el-table-column>
        <el-table-column prop="evidence" label="证据" min-width="210" />
      </el-table>
    </div>
  </section>
</template>

<script setup lang="ts">
import { computed, reactive, ref } from 'vue';
import { Check, Copy, Download, ListChecks, RotateCcw } from '@lucide/vue';
import { ElMessage } from 'element-plus';

type FieldStatus = 'PENDING' | 'PASS' | 'BLOCKED' | 'SKIP';

interface HandoffItem {
  id: string;
  category: '商户' | '微信' | '转账' | '硬件';
  title: string;
  expected: string;
  evidence: string;
}

interface HandoffDraft {
  status: FieldStatus;
  owner: string;
  note: string;
}

interface SessionMeta {
  batchNo: string;
  site: string;
  coordinator: string;
  executedAt: string;
}

const storageKey = 'qipai.cleaning.field-handoff';
const sessionStorageKey = 'qipai.cleaning.field-handoff.session';
const category = ref<'全部' | HandoffItem['category']>('全部');
const statusFilter = ref<'ALL' | FieldStatus>('ALL');
const bulkForm = reactive<{ status: FieldStatus; owner: string; note: string }>({
  status: 'PASS',
  owner: '',
  note: ''
});
const checklist: HandoffItem[] = [
  {
    id: 'merchant-credential',
    category: '商户',
    title: '商户凭据引用',
    expected: '确认 AppID、商户号、证书序列号、APIv3 Key 引用和平台证书均已配置。',
    evidence: '后台微信转账预检 PASS 截图或导出 CSV'
  },
  {
    id: 'merchant-scene',
    category: '商户',
    title: '商家转账场景报备',
    expected: '微信后台场景 ID、报备材料和通知 URL 与生产配置一致。',
    evidence: '场景 ID、通知 URL、微信后台审核状态'
  },
  {
    id: 'wechat-domain',
    category: '微信',
    title: '小程序合法域名',
    expected: 'request、uploadFile、downloadFile 均配置为 https://api.txyundm.cn。',
    evidence: '体验版真机请求、上传保洁照片、下载图片成功记录'
  },
  {
    id: 'wechat-openid',
    category: '微信',
    title: '保洁员 OpenID 绑定',
    expected: '参与转账的保洁员均显示已绑微信，未绑定人员不得进入真实转账。',
    evidence: '保洁员列表绑定状态和预检结果'
  },
  {
    id: 'transfer-small-amount',
    category: '转账',
    title: '小额真实转账',
    expected: '生产模式发起小额结算，返回待用户确认或成功状态并可主动同步。',
    evidence: '结算单号、微信转账流水、同步结果'
  },
  {
    id: 'transfer-notify',
    category: '转账',
    title: '微信回调入账',
    expected: '微信商家转账通知可验签、解密并幂等更新结算单状态。',
    evidence: '回调 traceId、结算单转账状态、重复通知结果'
  },
  {
    id: 'hardware-door',
    category: '硬件',
    title: '订单权限开门',
    expected: '有效订单本人在时间窗内开门成功，非本人或过期订单被拒绝。',
    evidence: '订单号、DeviceID、命令 ID、门锁回包'
  },
  {
    id: 'hardware-power',
    category: '硬件',
    title: '控电和插座联动',
    expected: '订单开始/结束可下发控电、插座任务，异常回包进入补偿或告警。',
    evidence: '控制箱通道、插座 DeviceID、ACK 和告警记录'
  }
];
const categoryOptions = ['全部', '商户', '微信', '转账', '硬件'];
const draft = reactive<Record<string, HandoffDraft>>(createInitialDraft());
const sessionMeta = reactive<SessionMeta>(readSessionMeta());

const filteredChecklist = computed(() => checklist.filter((item) => {
  const categoryMatched = category.value === '全部' || item.category === category.value;
  const statusMatched = statusFilter.value === 'ALL' || draft[item.id].status === statusFilter.value;
  return categoryMatched && statusMatched;
}));
const passedCount = computed(() => checklist.filter((item) => draft[item.id].status === 'PASS').length);
const blockedCount = computed(() => checklist.filter((item) => draft[item.id].status === 'BLOCKED').length);
const pendingCount = computed(() => checklist.filter((item) => draft[item.id].status === 'PENDING').length);
const blockedItems = computed(() => checklist.filter((item) => draft[item.id].status === 'BLOCKED'));

function createInitialDraft() {
  const saved = readSavedDraft();
  return Object.fromEntries(checklist.map((item) => [
    item.id,
    saved[item.id] || { status: 'PENDING', owner: '', note: '' }
  ])) as Record<string, HandoffDraft>;
}

function readSavedDraft() {
  try {
    return JSON.parse(localStorage.getItem(storageKey) || '{}') as Record<string, HandoffDraft>;
  } catch {
    return {};
  }
}

function persistDraft() {
  localStorage.setItem(storageKey, JSON.stringify(draft));
}

function readSessionMeta(): SessionMeta {
  try {
    const saved = JSON.parse(localStorage.getItem(sessionStorageKey) || '{}') as Partial<SessionMeta>;
    return {
      batchNo: saved.batchNo || '',
      site: saved.site || '',
      coordinator: saved.coordinator || '',
      executedAt: saved.executedAt || ''
    };
  } catch {
    return { batchNo: '', site: '', coordinator: '', executedAt: '' };
  }
}

function persistSessionMeta() {
  localStorage.setItem(sessionStorageKey, JSON.stringify(sessionMeta));
}

function resetDraft() {
  for (const item of checklist) {
    draft[item.id] = { status: 'PENDING', owner: '', note: '' };
  }
  persistDraft();
}

function applyBulkMark() {
  for (const item of filteredChecklist.value) {
    draft[item.id].status = bulkForm.status;
    if (bulkForm.owner.trim()) draft[item.id].owner = bulkForm.owner.trim();
    if (bulkForm.note.trim()) draft[item.id].note = bulkForm.note.trim();
  }
  persistDraft();
}

async function copyBlockedSummary() {
  const header = [
    `联调批次：${sessionMeta.batchNo || '未填写'}`,
    `现场/门店：${sessionMeta.site || '未填写'}`,
    `负责人：${sessionMeta.coordinator || '未填写'}`,
    `执行时间：${sessionMeta.executedAt || '未填写'}`
  ].join('\n');
  const content = blockedItems.value.map((item) => {
    const itemDraft = draft[item.id];
    return `[${item.category}] ${item.title} - ${itemDraft.owner || '未分派'} - ${itemDraft.note || item.expected}`;
  }).join('\n');
  try {
    await navigator.clipboard.writeText(`${header}\n\n${content}`);
    ElMessage.success('阻断摘要已复制');
  } catch {
    ElMessage.warning('当前浏览器不允许自动复制，请使用导出 CSV 留存');
  }
}

function exportChecklist() {
  downloadCsv(`cleaning-field-handoff-${Date.now()}.csv`, [
    ['类别', '字段', '值', '', '', '', '', ''],
    ['session', '联调批次', sessionMeta.batchNo, '', '', '', '', ''],
    ['session', '现场/门店', sessionMeta.site, '', '', '', '', ''],
    ['session', '负责人', sessionMeta.coordinator, '', '', '', '', ''],
    ['session', '执行时间', sessionMeta.executedAt, '', '', '', '', ''],
    ['ID', '类别', '检查项', '期望', '状态', '负责人', '结果记录', '证据'],
    ...checklist.map((item) => [
      item.id,
      item.category,
      item.title,
      item.expected,
      draft[item.id].status,
      draft[item.id].owner,
      draft[item.id].note,
      item.evidence
    ])
  ]);
}

function downloadCsv(filename: string, rows: string[][]) {
  const content = rows.map((row) => row.map(csvCell).join(',')).join('\r\n');
  const blob = new Blob([`\uFEFF${content}`], { type: 'text/csv;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  link.click();
  URL.revokeObjectURL(url);
}

function csvCell(value: string) {
  const normalized = value.replace(/\r?\n/g, ' ');
  return /[",\r\n]/.test(normalized) ? `"${normalized.replace(/"/g, '""')}"` : normalized;
}
</script>
