<template>
  <view class="page">
    <!-- Mobile 来源: ykt-management-mobile/src/pages/customer/followup-detail/followup-detail.vue -->
    <scroll-view scroll-y class="scroll">
      <view class="section">
        <view class="head-row">
          <view class="head-title">{{ currentType.label }}</view>
          <view class="head-tag" :class="`tag-${currentStatus.value}`">{{ currentStatus.label }}</view>
        </view>
        <view class="head-content">{{ form.taskContent || '暂无任务内容' }}</view>
      </view>

      <view v-if="todo?.sendContent" class="section border-top">
        <view class="sub-label">发送内容 ：</view>
        <view class="sub-content">{{ todo.sendContent }}</view>
        <view v-for="(f, idx) in showFileList" :key="idx" class="file-line">
          <text class="file-type">{{ f.typeStr }}</text>
          <text class="file-name">{{ f.name }}</text>
        </view>
      </view>

      <view class="section border-top kv">
        <view class="kv-left">计划执行时间：{{ planDate || '--' }}</view>
        <view class="kv-right">{{ executorDisplay || '--' }}</view>
      </view>
      <view class="section border-top kv">
        <view class="kv-left">客户:</view>
        <view class="kv-right link">{{ customerDisplay || '--' }}</view>
      </view>

      <view class="section mt-20">
        <view class="section-title">回访方式</view>
        <view class="method-row" @click="toggleMethod('phone')">
          <image class="radio" :src="`/static/circle${todoMethod === 'phone' ? 'd' : ''}.svg`" />
          <view class="method-label">电话</view>
          <view class="method-select" @click.stop="pickPhone">
            <view class="method-value" :class="{ muted: !phone }">{{ phone || '请选择号码' }}</view>
            <uni-icons type="arrowright" size="16" color="#999" />
          </view>
        </view>
        <view class="method-row" @click="toggleMethod('wechat')">
          <image class="radio" :src="`/static/circle${todoMethod === 'wechat' ? 'd' : ''}.svg`" />
          <view class="method-label">微信</view>
        </view>
      </view>

      <view class="section mt-20">
        <view class="section-title">回访结果</view>
        <view class="result-box">
          <textarea
            v-model="form.result"
            class="result-textarea"
            placeholder="请填写回访结果"
            maxlength="500"
            :disabled="!(editable || canEditResult)"
          />
        </view>
      </view>

      <view class="section mt-20 meta">
        <view class="meta-row">
          <text class="meta-key">创建人 :</text>
          <text class="meta-val">{{ creatorDisplay || '--' }}</text>
        </view>
        <view class="meta-row">
          <text class="meta-key">创建时间 :</text>
          <text class="meta-val">{{ createTimeStr || '--' }}</text>
        </view>
        <view v-if="endTimeStr" class="meta-row">
          <text class="meta-key">执行时间 :</text>
          <text class="meta-val">{{ endTimeStr }}</text>
        </view>
      </view>

      <view style="height: 160rpx" />
    </scroll-view>

    <view v-if="editable || canEditResult" class="footer">
      <button v-if="editable" class="footer-btn plain danger" @click="cancelTask">取消任务</button>
      <button v-if="editable" class="footer-btn primary" @click="markDone">设为完成</button>
      <button v-else class="footer-btn primary" @click="save">保存</button>
    </view>

    <view v-if="taskId && canRemove" class="delete-fab" @click="remove">
      <uni-icons type="trash" size="22" color="#ff4d4f" />
    </view>
  </view>
</template>

<script setup>
import { computed, reactive, ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import dayjs from 'dayjs';
import { storeToRefs } from 'pinia';
import api from '@/utils/api';
import useAccountStore from '@/store/account';
import { toast } from '@/utils/widget';
import { getTodoEventTypeLabel } from '@/utils/todo-const';

const archiveId = ref('');
const mode = ref('add');
const taskId = ref('');

const todo = ref(null);
const currentType = computed(() => ({ label: getTodoEventTypeLabel(todo.value?.eventType), value: String(todo.value?.eventType || '') }));
const customer = ref(null);
const userNameMap = ref({});

function statusLabelFromStatus(status) {
  const map = {
    processing: '待处理',
    notStart: '未开始',
    treated: '已完成',
    cancelled: '已取消',
    expired: '已过期',
  };
  return map[status] || '未知';
}

function getStatus(t) {
  const endOfToday = dayjs().endOf('day').valueOf();
  const startOfToday = dayjs().startOf('day').valueOf();
  const plannedExecutionTime = Number(t?.plannedExecutionTime || 0) || 0;
  const expireTime = Number(t?.expireTime || 0) || 0;
  const eventStatus = String(t?.eventStatus || '');

  if (eventStatus === 'treated') return 'treated';
  if (eventStatus === 'closed') return 'cancelled';
  if (eventStatus === 'expire') return 'expired';

  if (eventStatus === 'untreated') {
    if (expireTime && expireTime < startOfToday) return 'expired';
    if (plannedExecutionTime >= endOfToday) return 'notStart';
    if (plannedExecutionTime <= startOfToday && (!expireTime || expireTime >= endOfToday)) return 'processing';
    return 'processing';
  }
  return 'processing';
}

const currentStatus = computed(() => {
  const status = getStatus(todo.value);
  return { value: status, label: statusLabelFromStatus(status) };
});

const planDate = computed(() => {
  const v = todo.value?.plannedExecutionTime;
  return v && dayjs(v).isValid() ? dayjs(v).format('YYYY-MM-DD') : '';
});
const createTimeStr = computed(() => {
  const v = todo.value?.createTime;
  return v && dayjs(v).isValid() ? dayjs(v).format('YYYY-MM-DD HH:mm') : '';
});
const endTimeStr = computed(() => {
  const v = todo.value?.endTime;
  return v && dayjs(v).isValid() ? dayjs(v).format('YYYY-MM-DD HH:mm') : '';
});

const showFileList = computed(() => {
  const list = Array.isArray(todo.value?.fileList) ? todo.value.fileList : [];
  return list.map((i) => {
    const type = String(i?.type || '');
    const fileType = i?.file && typeof i.file.type === 'string' ? i.file.type : '';
    let typeStr = '';
    if (type === 'video' || fileType.includes('video')) typeStr = '【视频】';
    else if (type === 'image' || fileType.includes('image')) typeStr = '【图片】';
    else if (fileType === 'article') typeStr = '【文章】';
    else if (fileType === 'questionnaire') typeStr = '【问卷】';
    else if (type === 'link') typeStr = '【链接】';
    const name = i?.file?.name ? String(i.file.name) : '';
    return { typeStr, name };
  });
});

const accountStore = useAccountStore();
const { account, doctorInfo } = storeToRefs(accountStore);
const { getDoctorInfo } = accountStore;

const form = reactive({
  executorName: '',
  taskContent: '',
  result: '',
});

const todoMethod = ref('phone'); // phone | wechat
const phone = ref('');
const mobiles = computed(() => {
  const arr = [];
  const cached = uni.getStorageSync('ykt_case_archive_detail');
  if (cached && typeof cached === 'object') {
    if (cached.mobile) arr.push(String(cached.mobile));
    if (Array.isArray(cached.mobiles)) arr.push(...cached.mobiles.map(String));
  }
  const cleaned = arr.map((i) => String(i || '').trim()).filter(Boolean);
  if (!cleaned.includes('13800000000')) cleaned.push('13800000000');
  return Array.from(new Set(cleaned));
});

function getUserId() {
  const d = doctorInfo.value || {};
  const a = account.value || {};
  return String(d.userid || d.userId || d.corpUserId || a.userid || a.userId || '') || '';
}

function getCorpId() {
  const t = uni.getStorageSync('ykt_case_current_team') || {};
  const a = account.value || {};
  const d = doctorInfo.value || {};
  return String(t.corpId || a.corpId || d.corpId || '') || '';
}

async function ensureDoctor() {
  if (doctorInfo.value) return;
  if (!account.value?.openid) return;
  try {
    await getDoctorInfo();
  } catch {
    // ignore
  }
}

function resolveUserName(userId) {
  const id = String(userId || '');
  if (!id) return '';
  const map = userNameMap.value || {};
  return String(map[id] || '') || id;
}

async function loadUserNameMap(teamId) {
  if (!teamId) return;
  const corpId = getCorpId();
  if (!corpId) return;
  const res = await api('getTeamData', { corpId, teamId });
  if (!res?.success) return;
  const t = res?.data && typeof res.data === 'object' ? res.data : {};
  const list = Array.isArray(t.memberList) ? t.memberList : [];
  const map = list.reduce((acc, cur) => {
    const id = cur?.userid ? String(cur.userid) : '';
    if (!id) return acc;
    acc[id] = String(cur?.anotherName || cur?.name || cur?.userid || '');
    return acc;
  }, {});
  userNameMap.value = { ...(userNameMap.value || {}), ...map };
}

const isSelf = computed(() => {
  const id = getUserId();
  return Boolean(id && todo.value && String(todo.value.executorUserId || '') === id);
});
const editable = computed(() => isSelf.value && ['notStart', 'processing'].includes(currentStatus.value.value));
const canEditResult = computed(() => isSelf.value && ['treated', 'cancelled'].includes(currentStatus.value.value));

const canRemove = computed(() => {
  const t = todo.value;
  if (!t) return false;
  const userId = getUserId();
  return String(t.creatorUserId || '') === userId;
});

const executorDisplay = computed(() => {
  const t = todo.value || {};
  const name = resolveUserName(t.executorUserId);
  const teamName = String(t.executeTeamName || '');
  return teamName ? `${name}（${teamName}）` : name;
});
const creatorDisplay = computed(() => resolveUserName(todo.value?.creatorUserId));
const customerDisplay = computed(() => {
  const t = todo.value || {};
  const c = customer.value || {};
  return String(t.customerName || c.name || '');
});

onLoad((options) => {
  archiveId.value = options?.archiveId ? String(options.archiveId) : '';
  mode.value = options?.mode ? String(options.mode) : 'add';
  taskId.value = options?.id ? String(options.id) : '';

  const cached = uni.getStorageSync('ykt_case_archive_detail');
  if (cached && typeof cached === 'object') customer.value = cached;

  if (!taskId.value) {
    toast('缺少回访任务 id');
    setTimeout(() => uni.navigateBack(), 300);
    return;
  }
  getTodo();
});

function parseTodoMethod(value) {
  if (typeof value !== 'string') return { todoMethod: '', phone: '' };
  if (value.startsWith('phone')) {
    const [, num] = value.split(':');
    return { todoMethod: 'phone', phone: num || '' };
  }
  if (value === 'wechat') return { todoMethod: 'wechat', phone: '' };
  return { todoMethod: '', phone: '' };
}

function cancel() {
  uni.navigateBack();
}

function buildTodoMethodValue() {
  if (todoMethod.value === 'phone') return phone.value ? `phone:${phone.value}` : 'phone';
  if (todoMethod.value === 'wechat') return 'wechat';
  return '';
}

async function getTodo() {
  await ensureDoctor();
  const corpId = getCorpId();
  if (!corpId) {
    toast('缺少 corpId，请先完成登录/团队选择');
    return;
  }
  const res = await api('getTodoById', { corpId, id: taskId.value });
  if (!res?.success) {
    toast(res?.message || '获取回访任务失败');
    todo.value = null;
    return;
  }
  todo.value = res.data && typeof res.data === 'object' ? res.data : null;
  await loadUserNameMap(String(todo.value?.executeTeamId || ''));

  const parsed = parseTodoMethod(todo.value?.todoMethod);
  if (parsed.todoMethod) {
    todoMethod.value = parsed.todoMethod;
    phone.value = parsed.phone || '';
  } else if (editable.value) {
    todoMethod.value = 'phone';
    phone.value = mobiles.value[0] || '';
  }

  form.executorName = resolveUserName(todo.value?.executorUserId);
  form.taskContent = String(todo.value?.taskContent || '') || '';
  form.result = String(todo.value?.result || '') || '';
}

function toggleMethod(v) {
  if (!editable.value) return;
  todoMethod.value = v;
  if (v !== 'phone') phone.value = '';
}

function pickPhone() {
  if (!editable.value) return;
  if (todoMethod.value !== 'phone') return;
  uni.showActionSheet({
    itemList: mobiles.value,
    success: ({ tapIndex }) => {
      phone.value = mobiles.value[tapIndex] || '';
      todoMethod.value = 'phone';
    },
  });
}

function markDone() {
  if (!editable.value) return;
  if (!['phone', 'wechat'].includes(todoMethod.value)) return uni.showToast({ title: '请选择回访方式', icon: 'none' });
  uni.showModal({
    title: '提示',
    content: '确定完成该回访任务吗？',
    success: async (res) => {
      if (!res.confirm) return;
      await ensureDoctor();
      const corpId = getCorpId();
      const userId = getUserId();
      const methodValue = buildTodoMethodValue();
      const result = String(form.result || '').trim() || '已完成';
      const r = await api('setTodoStatus', { corpId, id: taskId.value, eventStatus: 'treated', result, userId, todoMethod: methodValue });
      if (!r?.success) return toast(r?.message || '操作失败');
      toast('操作成功');
      uni.$emit('archive-detail:followup-changed');
      setTimeout(() => uni.navigateBack(), 300);
    },
  });
}

function cancelTask() {
  if (!editable.value) return;
  uni.showModal({
    title: '提示',
    content: '确定取消该回访任务吗？',
    success: async (res) => {
      if (!res.confirm) return;
      await ensureDoctor();
      const corpId = getCorpId();
      const userId = getUserId();
      const methodValue = buildTodoMethodValue();
      const result = String(form.result || '').trim() || '已取消';
      const r = await api('setTodoStatus', { corpId, id: taskId.value, eventStatus: 'closed', result, userId, todoMethod: methodValue });
      if (!r?.success) return toast(r?.message || '操作失败');
      toast('取消成功');
      uni.$emit('archive-detail:followup-changed');
      setTimeout(() => uni.navigateBack(), 300);
    },
  });
}

async function save() {
  if (!canEditResult.value) return;
  if (String(form.result || '').trim() === '') return toast('请填写回访结果');
  await ensureDoctor();
  const corpId = getCorpId();
  if (!corpId) return toast('缺少 corpId');
  const methodValue = buildTodoMethodValue();
  const res = await api('updateTaskTodoResult', { corpId, id: taskId.value, result: String(form.result || ''), todoMethod: methodValue });
  if (!res?.success) return toast(res?.message || '操作失败');
  toast('操作成功');
  uni.$emit('archive-detail:followup-changed');
  setTimeout(() => uni.navigateBack(), 300);
}

function remove() {
  if (!canRemove.value) return;
  uni.showModal({
    title: '提示',
    content: '确定删除当前记录？',
    success: async (res) => {
      if (!res.confirm) return;
      await ensureDoctor();
      const corpId = getCorpId();
      const userId = getUserId();
      const r = await api('removeTodo', { corpId, userId, id: taskId.value });
      if (!r?.success) return toast(r?.message || '删除失败');
      uni.$emit('archive-detail:followup-changed');
      toast('已删除');
      setTimeout(() => uni.navigateBack(), 300);
    },
  });
}
</script>

<style scoped>
.page {
  height: 100vh;
  background: #f6f7f8;
}
.scroll {
  height: 100vh;
}
.section {
  background: #fff;
  padding: 24rpx 30rpx;
}
.border-top {
  border-top: 1px solid #e5e7eb;
}

.head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.head-title {
  font-size: 34rpx;
  font-weight: 600;
  color: #111827;
}
.head-tag {
  flex-shrink: 0;
  font-size: 26rpx;
  padding: 12rpx 20rpx;
  border-radius: 16rpx;
  background: #f3f4f6;
  color: #6b7280;
}
.tag-processing {
  background: #fee2e2;
  color: #ef4444;
}
.tag-notStart {
  background: #dbeafe;
  color: #2563eb;
}
.tag-treated {
  background: #dcfce7;
  color: #16a34a;
}
.tag-cancelled,
.tag-expired {
  background: #f3f4f6;
  color: #6b7280;
}
.head-content {
  margin-top: 24rpx;
  font-size: 30rpx;
  color: #6b7280;
  line-height: 44rpx;
}

.sub-label {
  font-size: 30rpx;
  color: #6b7280;
}
.sub-content {
  margin-top: 24rpx;
  font-size: 30rpx;
  color: #6b7280;
  line-height: 44rpx;
}
.file-line {
  margin-top: 12rpx;
  font-size: 30rpx;
  line-height: 40rpx;
}
.file-type {
  color: #111827;
  margin-right: 12rpx;
}
.file-name {
  color: #2563eb;
}

.section-title {
  font-size: 30rpx;
  font-weight: 600;
  color: #111827;
}
.method-row {
  display: flex;
  align-items: center;
  margin-top: 24rpx;
}
.radio {
  width: 32rpx;
  height: 32rpx;
  margin-right: 20rpx;
}
.method-label {
  font-size: 30rpx;
  color: #111827;
  margin-right: 20rpx;
}
.method-select {
  margin-left: auto;
  width: 400rpx;
  height: 60rpx;
  border: 1px solid #e5e7eb;
  border-radius: 16rpx;
  padding: 12rpx 20rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.method-value {
  font-size: 30rpx;
  color: #111827;
  max-width: 320rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.method-value.muted {
  color: #9ca3af;
}

.kv {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.kv-left {
  font-size: 30rpx;
  color: #6b7280;
}
.kv-right {
  font-size: 30rpx;
  color: #111827;
  max-width: 70%;
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kv-right.link {
  color: #2563eb;
  text-decoration: underline;
}

.mt-20 {
  margin-top: 20rpx;
}
.result-box {
  margin-top: 24rpx;
  padding: 20rpx;
  border: 1px solid #e5e7eb;
  border-radius: 16rpx;
}
.result-textarea {
  width: 100%;
  min-height: 160rpx;
  font-size: 30rpx;
  line-height: 48rpx;
  color: #111827;
  box-sizing: border-box;
}
.meta {
  font-size: 30rpx;
}
.meta-row {
  margin-top: 24rpx;
}
.meta-row:first-child {
  margin-top: 0;
}
.meta-key {
  color: #6b7280;
  margin-right: 12rpx;
}
.meta-val {
  color: #6b7280;
}

.footer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: #fff;
  display: flex;
  justify-content: flex-end;
  gap: 20rpx;
  padding: 30rpx;
  box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
}
.footer-btn {
  flex: 0 0 auto;
  min-width: 260rpx;
  height: 80rpx;
  line-height: 80rpx;
  border-radius: 16rpx;
  font-size: 30rpx;
}
.footer-btn::after {
  border: none;
}
.footer-btn.plain {
  background: #fff;
  color: #2563eb;
  border: 1px solid #2563eb;
}
.footer-btn.plain.danger {
  color: #ef4444;
  border-color: #ef4444;
}
.footer-btn.primary {
  background: #2563eb;
  color: #fff;
}

.delete-fab {
  position: fixed;
  right: 32rpx;
  bottom: calc(200rpx + env(safe-area-inset-bottom));
  width: 104rpx;
  height: 104rpx;
  border-radius: 52rpx;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 10rpx 18rpx rgba(0, 0, 0, 0.12);
  z-index: 30;
}
</style>
