<template>
  <el-drawer
    v-if="modelValue"
    :model-value="modelValue"
    direction="rtl"
    size="640px"
    :close-on-click-modal="true"
    :before-close="drawerDirtyGuard.beforeClose"
    :show-close="false"
    class="visit-editor-drawer"
    @update:model-value="emit('update:modelValue', $event)"
  >
    <template #header>
      <div class="editor-header">
        <div class="editor-title">{{ isEditing ? TEXT.common.actions.edit : TEXT.modules.subjectDetail.dialogVisit }}</div>
      </div>
    </template>

    <el-form :model="form" label-position="top" class="visit-editor-form">
      <div class="form-group">
        <div class="form-group-title">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="color:#3b82f6;flex-shrink:0"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
          {{ TEXT.modules.subjectDetail.dialogVisit }}
        </div>
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item :label="TEXT.common.fields.visitCode" required>
              <el-input v-model="form.visit_code" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="TEXT.common.fields.plannedDate" :required="!isEditing && isFirstVisit">
              <el-input v-if="isEditing" :model-value="displayDate(form.planned_date) || TEXT.common.fallback" disabled />
              <el-date-picker
                v-else
                v-model="form.planned_date"
                type="date"
                value-format="YYYY-MM-DD"
                :placeholder="TEXT.common.placeholders.select"
                class="full-width"
                :disabled="isFormReadOnly"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item :label="TEXT.common.fields.actualDate">
              <el-date-picker
                v-model="form.actual_date"
                type="date"
                value-format="YYYY-MM-DD"
                :placeholder="TEXT.common.placeholders.select"
                class="full-width"
                :disabled="isFormReadOnly"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="TEXT.common.fields.status">
              <el-tag
                :type="getVisitStatusTagType(getVisitStatus(form, form.actual_date))"
                effect="light"
                class="visit-status-tag"
              >
                {{ getVisitStatusLabel(form, form.actual_date) }}
              </el-tag>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item :label="TEXT.common.fields.notes">
          <el-input
            v-model="form.notes"
            type="textarea"
            :rows="3"
            :disabled="isFormReadOnly"
            :placeholder="TEXT.common.placeholders.input"
          />
        </el-form-item>
        <div v-if="isFormReadOnly" class="inactive-hint">
          <span class="hint-icon">!</span>
          <span>中心已停用，当前记录不可编辑</span>
        </div>
      </div>


    </el-form>

    <template #footer>
      <div class="drawer-footer">
        <el-button @click="emit('update:modelValue', false)">{{ TEXT.common.actions.cancel }}</el-button>
        <el-button type="primary" :loading="saving" :disabled="isFormReadOnly" @click="saveForm">
          {{ TEXT.common.actions.save }}
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { createVisit, updateVisit } from "../../api/visits";
import { useDrawerDirtyGuard } from "../../utils/drawerDirtyGuard";
import { TEXT } from "../../locales";
import { displayDate, displayEnum } from "../../utils/display";

const props = defineProps<{
  modelValue: boolean;
  studyId: string;
  subjectId: string;
  visit: any;
  isReadOnly?: boolean;
  canCreate?: boolean;
  canUpdate?: boolean;
}>();

const emit = defineEmits<{
  "update:modelValue": [value: boolean];
  saved: [];
}>();

const saving = ref(false);

const form = reactive({
  visit_code: "",
  planned_date: "",
  window_start: "",
  window_end: "",
  actual_date: "",
  notes: "",
});

const isEditing = computed(() => !!props.visit?.id);
const isFirstVisit = computed(() => form.visit_code === "V1");
const canSave = computed(() => (isEditing.value ? !!props.canUpdate : !!props.canCreate));
const isFormReadOnly = computed(() => !canSave.value || !!props.isReadOnly);

const drawerDirtyGuard = useDrawerDirtyGuard(() => ({
  form,
  attachments: [],
}));

const parseDate = (value?: string | null) => {
  if (!value) return null;
  const date = new Date(value);
  if (isNaN(date.getTime())) return null;
  return date;
};

const getVisitStatus = (row: any, actualDateOverride?: string) => {
  if (row?.status === "CANCELLED") return "CANCELLED";
  const actualDate = parseDate(actualDateOverride ?? row?.actual_date);
  const windowStart = parseDate(row?.window_start);
  const windowEnd = parseDate(row?.window_end);
  const plannedDate = parseDate(row?.planned_date);

  if (actualDate) {
    if ((windowStart && actualDate < windowStart) || (windowEnd && actualDate > windowEnd)) {
      return "OVERDUE";
    }
    return "DONE";
  }

  const today = new Date();
  const deadline = windowEnd || plannedDate;
  if (deadline && today > deadline) {
    return "LOST";
  }
  return "PLANNED";
};

const getVisitStatusTagType = (status: string) => {
  switch (status) {
    case "DONE": return "success";
    case "OVERDUE": return "warning";
    case "LOST": return "danger";
    case "CANCELLED": return "info";
    default: return "info";
  }
};

const getVisitStatusLabel = (row: any, actualDateOverride?: string) => {
  const status = getVisitStatus(row, actualDateOverride);
  if (status === "CANCELLED" && String(row?.notes || "").includes("提前终止")) {
    return "不适用";
  }
  return displayEnum(TEXT.enums.visitStatus, status);
};

const loadDetail = () => {
  form.visit_code = props.visit?.visit_code || "";
  form.planned_date = props.visit?.planned_date || "";
  form.window_start = props.visit?.window_start || "";
  form.window_end = props.visit?.window_end || "";
  form.actual_date = props.visit?.actual_date || "";
  form.notes = props.visit?.notes || "";
  drawerDirtyGuard.syncBaseline();
};

const saveForm = async () => {
  if (!props.studyId || !props.subjectId) return;
  if (isFormReadOnly.value) {
    ElMessage.warning(props.isReadOnly ? "中心已停用" : "权限不足");
    return;
  }
  if (!isEditing.value && isFirstVisit.value && !form.planned_date) {
    ElMessage.error("首次新增访视必须填写计划访视日期");
    return;
  }
  saving.value = true;
  try {
    if (isEditing.value) {
      const payload = {
        actual_date: form.actual_date || null,
        notes: form.notes || null,
      };
      await updateVisit(props.studyId, props.subjectId, props.visit.id, payload);

    } else {
      await createVisit(props.studyId, props.subjectId, {
        subject_id: props.subjectId,
        visit_code: form.visit_code,
        planned_date: form.planned_date || null,
        actual_date: form.actual_date || null,
        notes: form.notes || null,
      });
    }
    drawerDirtyGuard.syncBaseline();
    emit("update:modelValue", false);
    emit("saved");
    ElMessage.success(TEXT.common.messages.saveSuccess);
  } catch (e: any) {
    ElMessage.error(e?.response?.data?.message || TEXT.common.messages.saveFailed);
  } finally {
    saving.value = false;
  }
};

watch(
  () => props.modelValue,
  (visible) => {
    if (!visible) return;
    loadDetail();
  },
  { immediate: true },
);
</script>

<style scoped>
:deep(.visit-editor-drawer > .el-drawer__header) {
  margin-bottom: 0;
  padding: 22px 20px 8px;
}

:deep(.visit-editor-drawer > .el-drawer__body) {
  padding: 0 20px 4px;
}

.editor-header {
  display: flex;
  flex-direction: column;
}

.editor-title {
  font-size: 20px;
  font-weight: 700;
  color: var(--ctms-text-main);
  line-height: 1.2;
}

.visit-editor-form {
  padding: 0 4px 0 0;
}

.form-group {
  border: 1px solid #e8eef6;
  border-radius: 10px;
  padding: 16px 18px 8px;
  background: #fbfcfe;
  transition: border-color 0.2s ease;
}

.form-group:hover {
  border-color: #d0dced;
}

.form-group + .form-group {
  margin-top: 14px;
}

.form-group-title {
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 14px;
  color: #1a3560;
  display: flex;
  align-items: center;
  gap: 8px;
}

.full-width {
  width: 100%;
}

.inactive-hint {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: #fff7d6;
  border: 1px solid #fde68a;
  border-radius: 8px;
  font-size: 13px;
  color: #92400e;
  margin-bottom: 8px;
}

.hint-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #f59e0b;
  color: #ffffff;
  font-size: 12px;
  line-height: 1;
}

.drawer-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 10px 20px 16px;
}

.visit-status-tag {
  pointer-events: none;
}
</style>
