<template>
  <div class="tasks-container">
    <el-card shadow="never" class="panel-card">
      <div class="header-actions">
        <el-form :inline="true" :model="searchForm" class="search-form">
          <el-form-item label="目标医院" v-if="isSystemAdmin">
            <el-select
              v-model="searchForm.hospitalId"
              placeholder="全部医院"
              clearable
              filterable
              style="width: 240px"
            >
              <el-option
                v-for="hospital in hospitals"
                :key="hospital.id"
                :label="hospital.name"
                :value="hospital.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="任务状态">
            <el-select
              v-model="searchForm.status"
              placeholder="全部状态"
              clearable
              style="width: 180px"
            >
              <el-option
                v-for="item in statusOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="关键词">
            <el-input
              v-model="searchForm.keyword"
              placeholder="患者姓名 / 住院号 / 手机号 / 植入物名称 / 植入物型号"
              clearable
              style="width: 360px"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="Search" @click="handleSearch">
              查询
            </el-button>
            <el-button icon="Refresh" @click="resetSearch">重置</el-button>
          </el-form-item>
        </el-form>
      </div>

      <el-alert
        type="info"
        :closable="false"
        :title="pageAlertTitle"
        class="page-alert"
      />

      <el-table
        :data="tableData"
        v-loading="loading"
        border
        stripe
        style="width: 100%"
        empty-text="暂无调压记录"
      >
        <el-table-column prop="id" label="记录ID" width="90" align="center" />
        <el-table-column
          prop="taskId"
          label="任务ID"
          width="90"
          align="center"
        />
        <el-table-column label="任务状态" width="120" align="center">
          <template #default="{ row }">
            <el-tag :type="statusTagTypeMap[row.status] || 'info'">
              {{ statusTextMap[row.status] || row.status || '-' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          v-if="isSystemAdmin"
          label="医院"
          min-width="160"
          show-overflow-tooltip
        >
          <template #default="{ row }">
            {{ row.hospital?.name || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="患者" min-width="180" show-overflow-tooltip>
          <template #default="{ row }">
            <div>{{ row.patient?.name || '-' }}</div>
            <div class="sub-text">
              {{
                row.patient?.inpatientNo
                  ? `住院号 ${row.patient.inpatientNo}`
                  : '-'
              }}
            </div>
            <div class="sub-text">
              {{
                row.patient?.phone || row.patientPhone
                  ? `手机号 ${row.patient?.phone || row.patientPhone}`
                  : '手机号 -'
              }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="手术名称" min-width="180" show-overflow-tooltip>
          <template #default="{ row }">
            {{ row.surgery?.surgeryName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="设备" min-width="220" show-overflow-tooltip>
          <template #default="{ row }">
            <div>
              {{ row.device?.implantName || row.device?.implantModel || '-' }}
            </div>
            <div class="sub-text">{{ row.device?.implantModel || '-' }}</div>
          </template>
        </el-table-column>
        <el-table-column label="压力变化" min-width="140" align="center">
          <template #default="{ row }">
            {{ formatPressureChange(row) }}
          </template>
        </el-table-column>
        <el-table-column label="当前压力" width="110" align="center">
          <template #default="{ row }">
            {{ formatValue(row.currentPressure) }}
          </template>
        </el-table-column>
        <el-table-column label="创建人" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">
            {{ row.creator?.name || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="接收人" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">
            {{ row.engineer?.name || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="发布时间" min-width="170" align="center">
          <template #default="{ row }">
            {{ formatDateTime(row.createdAt) }}
          </template>
        </el-table-column>
        <el-table-column label="完成凭证" min-width="260">
          <template #default="{ row }">
            <div
              v-if="
                Array.isArray(row.completionMaterials) &&
                row.completionMaterials.length > 0
              "
              class="completion-preview-list"
            >
              <div
                v-for="(material, index) in row.completionMaterials"
                :key="material.assetId || material.url || index"
                class="completion-preview-card"
              >
                <div class="completion-preview-name">
                  {{ material.name || material.type || '完成凭证' }}
                </div>
                <el-image
                  v-if="isImageMaterial(material)"
                  :src="material.url"
                  :preview-src-list="[material.url]"
                  preview-teleported
                  fit="contain"
                  class="completion-preview-image"
                />
                <video
                  v-else-if="isVideoMaterial(material)"
                  :src="material.url"
                  class="completion-preview-video"
                  controls
                  preload="metadata"
                />
                <a
                  v-else-if="material.url"
                  :href="material.url"
                  target="_blank"
                  rel="noreferrer"
                  class="completion-preview-link"
                >
                  查看文件
                </a>
              </div>
            </div>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="220" fixed="right" align="center">
          <template #default="{ row }">
            <el-button
              v-if="canAccept(row)"
              size="small"
              type="primary"
              :loading="actionTaskId === row.taskId && actionType === 'accept'"
              @click="handleAccept(row)"
            >
              接收
            </el-button>
            <el-button
              v-if="canCancel(row)"
              size="small"
              type="danger"
              plain
              :loading="actionTaskId === row.taskId && actionType === 'cancel'"
              @click="handleCancel(row)"
            >
              {{ getCancelButtonText(row) }}
            </el-button>
            <el-button
              v-if="canComplete(row)"
              size="small"
              type="success"
              @click="openCompleteDialog(row)"
            >
              完成
            </el-button>
            <span v-if="!canAccept(row) && !canCancel(row) && !canComplete(row)"
              >-</span
            >
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination-container">
        <el-pagination
          v-model:current-page="page"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          background
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handlePageChange"
          @current-change="handlePageChange"
        />
      </div>
    </el-card>

    <el-dialog
      v-model="completeDialogVisible"
      title="完成调压任务"
      width="720px"
      destroy-on-close
      @closed="resetCompleteDialog"
    >
      <el-alert
        type="info"
        :closable="false"
        title="完成前请先上传至少一张图片或一个视频凭证，完成后系统才会更新当前压力。"
      />

      <div v-if="completeDialogRow" class="complete-summary-card">
        <div class="complete-summary-line">
          <span class="summary-label">患者</span>
          <span>{{ completeDialogRow.patient?.name || '-' }}</span>
        </div>
        <div class="complete-summary-line">
          <span class="summary-label">设备</span>
          <span>
            {{
              completeDialogRow.device?.implantName ||
              completeDialogRow.device?.implantModel ||
              '-'
            }}
          </span>
        </div>
        <div class="complete-summary-line">
          <span class="summary-label">目标挡位</span>
          <span>{{ formatPressureChange(completeDialogRow) }}</span>
        </div>
      </div>

      <div class="complete-upload-actions">
        <AssetUploadButton
          button-text="上传图片或视频"
          button-type="primary"
          accept="image/*,video/*"
          :hospital-id="uploadHospitalId"
          @uploaded="handleCompletionUploaded"
        />
      </div>

      <div v-if="completionMaterials.length === 0" class="empty-hint">
        请先上传完成凭证
      </div>

      <div v-else class="completion-preview-list dialog-preview-list">
        <div
          v-for="(material, index) in completionMaterials"
          :key="material.assetId || material.url || index"
          class="completion-preview-card dialog-preview-card"
        >
          <div class="completion-preview-name">
            {{ material.name || material.type || '完成凭证' }}
          </div>
          <el-image
            v-if="isImageMaterial(material)"
            :src="material.url"
            :preview-src-list="[material.url]"
            preview-teleported
            fit="contain"
            class="completion-preview-image"
          />
          <video
            v-else-if="isVideoMaterial(material)"
            :src="material.url"
            class="completion-preview-video"
            controls
            preload="metadata"
          />
          <a
            v-else-if="material.url"
            :href="material.url"
            target="_blank"
            rel="noreferrer"
            class="completion-preview-link"
          >
            查看文件
          </a>
          <el-button
            type="danger"
            plain
            size="small"
            @click="removeCompletionMaterial(index)"
          >
            删除
          </el-button>
        </div>
      </div>

      <template #footer>
        <el-button @click="completeDialogVisible = false">关闭</el-button>
        <el-button
          type="primary"
          :loading="completeSubmitting"
          @click="submitComplete"
        >
          确认完成
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import AssetUploadButton from '../../components/AssetUploadButton.vue';
import {
  acceptTask,
  cancelTask,
  completeTask,
  getTasks,
} from '../../api/tasks';
import { getHospitals } from '../../api/organization';
import { useUserStore } from '../../store/user';

const userStore = useUserStore();

const isSystemAdmin = computed(() => userStore.role === 'SYSTEM_ADMIN');
const isEngineer = computed(() => userStore.role === 'ENGINEER');
const canCreatorCancel = computed(() =>
  ['SYSTEM_ADMIN', 'HOSPITAL_ADMIN', 'DOCTOR', 'DIRECTOR', 'LEADER'].includes(
    userStore.role,
  ),
);
const currentUserId = computed(() => userStore.userInfo?.id || null);
const uploadHospitalId = computed(() => userStore.userInfo?.hospitalId || null);
const pageAlertTitle = computed(() =>
  isEngineer.value
    ? '待接收任务可在本页直接接收；已接收任务可取消接收或上传图片/视频后完成。'
    : '调压任务请到患者页面发布；工程师在本页接收、取消和完成，本页同时用于查看调压记录。',
);

const statusOptions = [
  { label: '待接收', value: 'PENDING' },
  { label: '已接收', value: 'ACCEPTED' },
  { label: '已完成', value: 'COMPLETED' },
  { label: '已取消', value: 'CANCELLED' },
];

const statusTextMap = {
  PENDING: '待接收',
  ACCEPTED: '已接收',
  COMPLETED: '已完成',
  CANCELLED: '已取消',
};

const statusTagTypeMap = {
  PENDING: 'warning',
  ACCEPTED: 'primary',
  COMPLETED: 'success',
  CANCELLED: 'info',
};

const loading = ref(false);
const actionTaskId = ref(null);
const actionType = ref('');
const hospitals = ref([]);
const tableData = ref([]);
const total = ref(0);
const page = ref(1);
const pageSize = ref(20);
const completeDialogVisible = ref(false);
const completeSubmitting = ref(false);
const completeDialogRow = ref(null);
const completionMaterials = ref([]);

const searchForm = reactive({
  hospitalId: null,
  status: '',
  keyword: '',
});

function formatDateTime(value) {
  if (!value) {
    return '-';
  }

  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return '-';
  }

  return date.toLocaleString('zh-CN', { hour12: false });
}

function formatValue(value) {
  return value == null || value === '' ? '-' : value;
}

function formatPressureChange(row) {
  return `${formatValue(row.oldPressure)} -> ${formatValue(row.targetPressure)}`;
}

function canAccept(row) {
  return isEngineer.value && row?.status === 'PENDING';
}

function canComplete(row) {
  return (
    isEngineer.value &&
    row?.status === 'ACCEPTED' &&
    row?.engineer?.id === currentUserId.value
  );
}

function canCancel(row) {
  const canEngineerRelease =
    isEngineer.value &&
    row?.status === 'ACCEPTED' &&
    row?.engineer?.id === currentUserId.value;

  const canCreatorCancelTask =
    canCreatorCancel.value &&
    row?.status &&
    ['PENDING', 'ACCEPTED'].includes(row.status) &&
    row?.creator?.id === currentUserId.value;

  return canEngineerRelease || canCreatorCancelTask;
}

function getCancelButtonText(row) {
  const isEngineerRelease =
    isEngineer.value &&
    row?.status === 'ACCEPTED' &&
    row?.engineer?.id === currentUserId.value;

  return isEngineerRelease ? '取消接收' : '取消任务';
}

function isImageMaterial(material) {
  return material?.type === 'IMAGE';
}

function isVideoMaterial(material) {
  return material?.type === 'VIDEO';
}

function normalizeCompletionMaterial(asset) {
  return {
    assetId: asset.id,
    type: asset.type,
    url: asset.url,
    name: asset.originalName || asset.fileName || asset.name || '完成凭证',
  };
}

async function fetchHospitalsForAdmin() {
  if (!isSystemAdmin.value) {
    return;
  }

  const res = await getHospitals({ page: 1, pageSize: 100 });
  hospitals.value = Array.isArray(res?.list) ? res.list : [];
}

async function fetchData() {
  loading.value = true;

  try {
    const params = {
      page: page.value,
      pageSize: pageSize.value,
    };

    if (isSystemAdmin.value && searchForm.hospitalId) {
      params.hospitalId = searchForm.hospitalId;
    }
    if (searchForm.status) {
      params.status = searchForm.status;
    }
    if (String(searchForm.keyword || '').trim()) {
      params.keyword = String(searchForm.keyword || '').trim();
    }

    const res = await getTasks(params);
    tableData.value = Array.isArray(res?.list) ? res.list : [];
    total.value = Number(res?.total || 0);
  } finally {
    loading.value = false;
  }
}

async function handleSearch() {
  page.value = 1;
  await fetchData();
}

async function resetSearch() {
  searchForm.hospitalId = null;
  searchForm.status = '';
  searchForm.keyword = '';
  page.value = 1;
  pageSize.value = 20;
  await fetchData();
}

async function handlePageChange() {
  await fetchData();
}

async function handleAccept(row) {
  actionTaskId.value = row.taskId;
  actionType.value = 'accept';
  try {
    await acceptTask({ taskId: row.taskId });
    ElMessage.success('任务已接收');
    await fetchData();
  } finally {
    actionTaskId.value = null;
    actionType.value = '';
  }
}

function openCompleteDialog(row) {
  completeDialogRow.value = row;
  completionMaterials.value = [];
  completeDialogVisible.value = true;
}

function resetCompleteDialog() {
  completeDialogRow.value = null;
  completionMaterials.value = [];
  completeSubmitting.value = false;
}

function handleCompletionUploaded(asset) {
  if (!isImageMaterial(asset) && !isVideoMaterial(asset)) {
    ElMessage.error('完成任务仅支持图片或视频凭证');
    return;
  }

  const material = normalizeCompletionMaterial(asset);
  const existed = completionMaterials.value.some(
    (item) => item.assetId === material.assetId,
  );
  if (existed) {
    ElMessage.warning('该凭证已添加');
    return;
  }

  completionMaterials.value = [...completionMaterials.value, material];
}

function removeCompletionMaterial(index) {
  completionMaterials.value.splice(index, 1);
}

async function handleCancel(row) {
  const isEngineerRelease =
    isEngineer.value && row?.status === 'ACCEPTED' && row?.engineer?.id === currentUserId.value;
  const confirmTitle = isEngineerRelease ? '取消接收' : '取消任务';
  const confirmText = isEngineerRelease
    ? '取消接收后，任务会退回待接收状态，其他同院工程师可重新接收，是否继续？'
    : '取消后任务将变更为已取消状态，是否继续？';
  const confirmButtonText = isEngineerRelease ? '确认取消接收' : '确认取消任务';
  const successText = isEngineerRelease ? '任务已退回待接收' : '任务已取消';

  try {
    await ElMessageBox.confirm(
      confirmText,
      confirmTitle,
      {
        type: 'warning',
        confirmButtonText,
        cancelButtonText: '返回',
      },
    );
  } catch {
    return;
  }

  actionTaskId.value = row.taskId;
  actionType.value = 'cancel';
  try {
    await cancelTask({ taskId: row.taskId });
    ElMessage.success(successText);
    await fetchData();
  } finally {
    actionTaskId.value = null;
    actionType.value = '';
  }
}

async function submitComplete() {
  if (!completeDialogRow.value) {
    return;
  }
  if (completionMaterials.value.length === 0) {
    ElMessage.error('请先上传至少一张图片或一个视频');
    return;
  }

  actionTaskId.value = completeDialogRow.value.taskId;
  actionType.value = 'complete';
  completeSubmitting.value = true;
  try {
    await completeTask({
      taskId: completeDialogRow.value.taskId,
      completionMaterials: completionMaterials.value.map((item) => ({
        assetId: item.assetId,
        type: item.type,
        url: item.url,
        name: item.name,
      })),
    });
    ElMessage.success('任务已完成');
    completeDialogVisible.value = false;
    resetCompleteDialog();
    await fetchData();
  } finally {
    actionTaskId.value = null;
    actionType.value = '';
    completeSubmitting.value = false;
  }
}

onMounted(async () => {
  await fetchHospitalsForAdmin();
  await fetchData();
});
</script>

<style scoped>
.tasks-container {
  padding: 0;
}

.panel-card {
  border-radius: 18px;
}

.header-actions {
  margin-bottom: 16px;
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 0;
}

.page-alert {
  margin-bottom: 16px;
}

.sub-text {
  margin-top: 4px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.empty-hint {
  padding: 24px 0;
  color: var(--el-text-color-secondary);
  text-align: center;
}

.complete-summary-card {
  margin-top: 16px;
  padding: 16px;
  border-radius: 14px;
  background: #f8fafc;
}

.complete-summary-line {
  display: flex;
  gap: 12px;
  align-items: center;
}

.complete-summary-line + .complete-summary-line {
  margin-top: 10px;
}

.summary-label {
  width: 72px;
  color: var(--el-text-color-secondary);
}

.complete-upload-actions {
  margin: 16px 0;
}

.completion-preview-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.completion-preview-card {
  width: 112px;
}

.dialog-preview-list {
  margin-top: 16px;
}

.dialog-preview-card {
  width: 140px;
}

.completion-preview-name {
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  word-break: break-all;
}

.completion-preview-image,
.completion-preview-video {
  width: 100%;
  height: 96px;
  border-radius: 12px;
  background: #eef2f7;
}

.completion-preview-image {
  overflow: hidden;
}

.completion-preview-image :deep(.el-image__inner) {
  object-fit: contain;
}

.completion-preview-video {
  object-fit: contain;
}

.completion-preview-link {
  display: inline-block;
  color: var(--el-color-primary);
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}
</style>
