<script setup lang="ts">
/* eslint-disable vue/no-mutating-props, no-plusplus, unicorn/prefer-dom-node-text-content, @typescript-eslint/no-dynamic-delete */
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
import { ElMessage } from 'element-plus';
import { RDMS_REQ_PRIORITY_DICT_CODE } from '@/constants/dict';
import { useDict } from '@/hooks/business/dict';
import DictSelect from '@/components/custom/dict-select.vue';
import { formatPeriodLabel } from '../../shared/types';

const props = defineProps<{
  reportType: string;
  period: string;
  mode?: 'add' | 'edit' | 'detail';
  scene?: 'fill' | 'detail' | 'approval';
  baseInfo?: Api.WorkReport.Project.ProjectReport | null;
  model: Api.WorkReport.Project.ProjectReportSaveParams;
}>();

const emit = defineEmits<{
  back: [];
  save: [];
  submit: [];
  requestApprove: [];
  requestReject: [];
  pullDefaultDraft: [];
}>();

interface WorkItem {
  id: string;
  title: string;
  days?: number;
  hours?: number;
  priority: string;
  progress: number;
  removable?: boolean;
  source?: Api.WorkReport.Project.ProjectReportItem;
  sourceIndex?: number;
}

const activeEditField = ref('');
const inlinePlanVisible = ref(false);
const titleEditSnapshot = ref<Record<string, string>>({});
const EMPTY_TEXT = '本周期内暂无数据';
const isReadonly = computed(() => props.mode === 'detail' || props.scene === 'approval');
const { dictData: priorityDictData, getLabel: getPriorityLabel } = useDict(RDMS_REQ_PRIORITY_DICT_CODE);

const projectForm = reactive({
  get projectName() {
    return props.baseInfo?.projectName || '--';
  },
  get projectOwner() {
    return props.baseInfo?.projectOwnerName || '--';
  },
  get technicalOwner() {
    return props.baseInfo?.technicalOwnerName || '--';
  },
  get members() {
    return (props.baseInfo?.projectMemberSnapshot || []).map(item => item.userName);
  },
  get projectStatus() {
    return props.model.projectStatusDesc || '';
  },
  set projectStatus(value: string) {
    props.model.projectStatusDesc = value;
  },
  get progressPlan() {
    return props.model.projectProgressPlan || '';
  },
  set progressPlan(value: string) {
    props.model.projectProgressPlan = value;
  },
  get keyPoints() {
    return props.model.projectKeyPoints || '';
  },
  set keyPoints(value: string) {
    props.model.projectKeyPoints = value;
  },
  get problems() {
    return props.model.projectProblems || '';
  },
  set problems(value: string) {
    props.model.projectProblems = value;
  }
});

const planForm = ref({
  title: '',
  priority: '3' as WorkItem['priority'],
  progress: 0
});

function normalizePriorityCode(value?: string | number | null) {
  const text = String(value ?? '').trim();
  if (!text) return '';

  const matchedByValue = priorityDictData.value.find(item => String(item.value) === text);
  if (matchedByValue) return String(matchedByValue.value);

  const matchedByLabel = priorityDictData.value.find(item => item.label === text);
  if (matchedByLabel) return String(matchedByLabel.value);

  const priorityLabelMatch = text.match(/^P(\d+)$/iu);
  if (priorityLabelMatch) return priorityLabelMatch[1];

  return text;
}

function resolvePriorityLabel(value?: string | number | null) {
  const priorityCode = normalizePriorityCode(value);
  if (!priorityCode) return '';
  return getPriorityLabel(priorityCode, {
    fallback: /^P\d+$/iu.test(priorityCode) ? priorityCode : `P${priorityCode}`
  });
}

function toWorkItem(item: Api.WorkReport.Project.ProjectReportItem, index: number, removable: boolean): WorkItem {
  return {
    id: item.id || `${removable ? 'next' : 'current'}-${index}`,
    title: item.itemTitle || '未命名工作',
    hours: item.workHours || 0,
    priority: normalizePriorityCode(item.priorityCode) || '3',
    progress: item.progressRate || 0,
    removable,
    source: item,
    sourceIndex: index
  };
}

const currentWorks = computed<WorkItem[]>(() => {
  return (props.model.currentItems || []).map((item, index) => toWorkItem(item, index, true));
});

const nextPlans = computed<WorkItem[]>(() => {
  return (props.model.nextItems || []).map((item, index) => toWorkItem(item, index, true));
});

const MAX_VISIBLE_MEMBERS = 5;
/** 最多显示的成员数：受容器宽度动态限制 */
const maxVisibleMemberCount = ref(MAX_VISIBLE_MEMBERS);
const memberChipsEl = ref<HTMLElement | null>(null);
let memberResizeObserver: ResizeObserver | null = null;

function measureChipWidth(text: string): number {
  // 估算 chip 宽度：8px 左右内边距 + 中文每字 12px、英文每字 7px
  let width = 16;
  for (const ch of text) {
    width += /[\u4E00-\u9FA5]/.test(ch) ? 12 : 7;
  }
  return Math.ceil(width);
}

/** 根据容器宽度动态计算可容纳的成员数，上限为 MAX_VISIBLE_MEMBERS */
function measureVisibleCount() {
  const el = memberChipsEl.value;
  if (!el) return;

  const containerWidth = el.clientWidth - 16; // 减去 padding
  const members = projectForm.members;
  if (!members.length) {
    maxVisibleMemberCount.value = 0;
    return;
  }

  // 先快速按数量上限分配，再校验总宽度
  const moreChipWidth = 28; // +N 的预估宽度
  const gap = 6;

  let count = Math.min(members.length, MAX_VISIBLE_MEMBERS);
  for (; count > 0; count--) {
    const showMore = count < members.length;
    const reserved = showMore ? moreChipWidth + gap : 0;
    let total = reserved;
    for (let i = 0; i < count; i++) {
      total += measureChipWidth(members[i]) + gap;
    }
    if (total <= containerWidth) break;
  }

  maxVisibleMemberCount.value = count;
}

const visibleMembers = computed(() => projectForm.members.slice(0, maxVisibleMemberCount.value));
const hiddenMembers = computed(() => projectForm.members.slice(maxVisibleMemberCount.value));

onMounted(() => {
  if (!memberResizeObserver && typeof ResizeObserver !== 'undefined') {
    memberResizeObserver = new ResizeObserver(() => measureVisibleCount());
  }
  if (memberChipsEl.value) {
    memberResizeObserver?.observe(memberChipsEl.value);
    nextTick(measureVisibleCount);
  }
});

watch(memberChipsEl, el => {
  memberResizeObserver?.disconnect();
  if (el) {
    memberResizeObserver?.observe(el);
    nextTick(measureVisibleCount);
  }
});

watch(
  () => projectForm.members.length,
  () => {
    nextTick(measureVisibleCount);
  }
);

onBeforeUnmount(() => {
  memberResizeObserver?.disconnect();
  memberResizeObserver = null;
});
const totalHours = computed(() => {
  const baseTotalWorkHours = Number(props.baseInfo?.totalWorkHours ?? 0);
  if (Number.isFinite(baseTotalWorkHours) && baseTotalWorkHours > 0) return baseTotalWorkHours;

  return (props.model.currentItems || []).reduce((sum, item) => sum + Number(item.workHours || 0), 0);
});
const isDuplicatePlanTitle = computed(() => {
  const title = planForm.value.title.trim();
  return Boolean(title) && (props.model.nextItems || []).some(item => item.itemTitle.trim() === title);
});

function focusEditField(key: string) {
  activeEditField.value = key;
}

function blurEditField(key: string) {
  if (activeEditField.value === key) activeEditField.value = '';
}

function syncRichProjectField(field: 'projectStatus' | 'progressPlan' | 'keyPoints' | 'problems', event: Event) {
  const target = event.currentTarget as HTMLElement;
  projectForm[field] = target.innerText.trim();
  blurEditField(field);
}

function resetPlanForm() {
  planForm.value = { title: '', priority: '3', progress: 0 };
}

function showInlinePlanForm() {
  inlinePlanVisible.value = true;
  resetPlanForm();
}

function cancelInlinePlan() {
  inlinePlanVisible.value = false;
  resetPlanForm();
}

function submitInlinePlan() {
  const title = planForm.value.title.trim();
  if (!title) return;
  if (isDuplicatePlanTitle.value) {
    ElMessage.warning('计划名称重复，请调整后再新增');
    return;
  }
  props.model.nextItems.push({
    itemTitle: planForm.value.title.trim(),
    workHours: 0,
    priorityCode: normalizePriorityCode(planForm.value.priority),
    progressRate: planForm.value.progress,
    _isNew: true
  } as Api.WorkReport.Project.ProjectReportItem & { _isNew: boolean });
  resetPlanForm();
  inlinePlanVisible.value = false;
}

function removePlanItem(index: number) {
  const item = nextPlans.value[index];
  if (item?.sourceIndex !== undefined) props.model.nextItems.splice(item.sourceIndex, 1);
}

function removeCurrentWorkItem(index: number) {
  const item = currentWorks.value[index];
  if (item?.sourceIndex !== undefined) props.model.currentItems.splice(item.sourceIndex, 1);
}

function startTitleEdit(item: WorkItem) {
  titleEditSnapshot.value[item.id] = item.title;
}

function notifyTitleSaved(item: WorkItem) {
  const previousTitle = titleEditSnapshot.value[item.id] ?? item.title;
  const nextTitle = item.title.trim();
  if (!nextTitle) {
    item.title = previousTitle;
    delete titleEditSnapshot.value[item.id];
    return;
  }
  item.title = nextTitle;
  if (item.source) item.source.itemTitle = nextTitle;
  delete titleEditSnapshot.value[item.id];
  // if (nextTitle !== previousTitle) {
  //   ElMessage.success('名称已成功修改');
  // }
}
</script>

<template>
  <div class="card form-page">
    <div class="section">
      <div class="section-title">
        <span>基础信息</span>
        <div v-if="mode === 'edit' && !isReadonly" class="section-title-right">
          <ElButton size="small" plain type="primary" @click="emit('pullDefaultDraft')">
            <template #icon>
              <icon-mdi-refresh class="text-icon" />
            </template>
            刷新
          </ElButton>
        </div>
      </div>
      <div class="compose-grid">
        <div class="field">
          <label>项目名称</label>
          <ElInput v-model="projectForm.projectName" disabled />
        </div>
        <div class="field">
          <label>项目负责人</label>
          <ElInput v-model="projectForm.projectOwner" disabled />
        </div>
        <div class="field">
          <label>技术负责人</label>
          <ElInput v-model="projectForm.technicalOwner" disabled />
        </div>
        <div class="field members-field">
          <label>项目组成员</label>
          <div ref="memberChipsEl" class="member-chips">
            <span v-for="member in visibleMembers" :key="member" class="member-chip">{{ member }}</span>
            <ElTooltip v-if="hiddenMembers.length" placement="top" :content="hiddenMembers.join('、')">
              <span class="member-chip more">+{{ hiddenMembers.length }}</span>
            </ElTooltip>
          </div>
        </div>
      </div>
      <div class="basic-status-editor">
        <label>项目状况</label>
        <div
          class="rich-editor"
          :contenteditable="!isReadonly"
          spellcheck="false"
          :data-placeholder="isReadonly ? undefined : '请输入项目状况'"
          @focus="focusEditField('projectStatus')"
          @blur="syncRichProjectField('projectStatus', $event)"
        >
          {{ projectForm.projectStatus }}
        </div>
      </div>
    </div>

    <div class="section">
      <div class="section-title">整体计划进度</div>
      <div class="single-editor">
        <div
          class="rich-editor"
          :contenteditable="!isReadonly"
          spellcheck="false"
          :data-placeholder="isReadonly ? undefined : '请输入整体计划进度'"
          @focus="focusEditField('progressPlan')"
          @blur="syncRichProjectField('progressPlan', $event)"
        >
          {{ projectForm.progressPlan }}
        </div>
      </div>
    </div>

    <div class="section">
      <div class="section-title">
        <div class="section-title-left">
          <span>本期工作内容</span>
          <span class="source-chip">{{ currentWorks.length }} 项工作</span>
          <span class="source-chip">共 {{ totalHours }}h</span>
        </div>
      </div>
      <div class="review-grid layout-row">
        <div v-if="!currentWorks.length">{{ EMPTY_TEXT }}</div>
        <div v-for="(item, index) in currentWorks" :key="item.id" class="review-card compact-work-card">
          <div class="review-card-head" :class="{ 'no-remove': item.removable === false }">
            <span class="row-index">{{ index + 1 }}</span>
            <div class="review-title-readonly">
              <div class="work-title-line">
                <input
                  v-model="item.title"
                  class="work-title-input"
                  aria-label="本期工作内容名称"
                  :disabled="isReadonly"
                  @focus="startTitleEdit(item)"
                  @blur="notifyTitleSaved(item)"
                />
                <span class="meta-chip priority-chip">{{ resolvePriorityLabel(item.priority) }}</span>
                <span class="meta-chip">进度 {{ item.progress }}%</span>
                <span class="meta-chip">共 {{ item.hours }}h</span>
              </div>
            </div>
            <ElPopconfirm
              v-if="item.removable !== false && !isReadonly"
              title="确认删除这条工作内容吗？"
              confirm-button-text="删除"
              cancel-button-text="取消"
              width="220"
              @confirm="removeCurrentWorkItem(index)"
            >
              <template #reference>
                <button class="item-remove-btn" aria-label="删除工作内容">×</button>
              </template>
            </ElPopconfirm>
          </div>
        </div>
      </div>
    </div>

    <div class="section">
      <div class="section-title">
        <div class="section-title-left">
          <span>下期计划工作内容</span>
          <span class="source-chip">{{ nextPlans.length }} 项计划</span>
        </div>
        <div class="section-title-right">
          <ElButton v-if="!isReadonly" size="small" :disabled="inlinePlanVisible" @click="showInlinePlanForm">
            新增计划
          </ElButton>
        </div>
      </div>
      <div class="plan-list layout-row">
        <div v-if="!nextPlans.length && !inlinePlanVisible">{{ EMPTY_TEXT }}</div>
        <div v-for="(item, index) in nextPlans" :key="item.id" class="plan-card compact-work-card">
          <div class="plan-card-head" :class="{ 'no-remove': item.removable === false }">
            <span class="row-index">{{ index + 1 }}</span>
            <div class="plan-title-readonly">
              <div class="work-title-line">
                <input
                  v-model="item.title"
                  class="work-title-input"
                  aria-label="下期计划工作内容名称"
                  :disabled="isReadonly"
                  @focus="startTitleEdit(item)"
                  @blur="notifyTitleSaved(item)"
                />
                <span class="meta-chip priority-chip">{{ resolvePriorityLabel(item.priority) }}</span>
                <span class="meta-chip">进度 {{ item.progress }}%</span>
              </div>
            </div>
            <ElPopconfirm
              v-if="item.removable !== false && !isReadonly"
              title="确认删除这条计划吗？"
              confirm-button-text="删除"
              cancel-button-text="取消"
              width="220"
              @confirm="removePlanItem(index)"
            >
              <template #reference>
                <button class="item-remove-btn" aria-label="删除计划">×</button>
              </template>
            </ElPopconfirm>
          </div>
        </div>
        <div v-if="inlinePlanVisible && !isReadonly" class="plan-card compact-work-card inline-plan-card">
          <div class="plan-card-head">
            <span class="row-index">{{ nextPlans.length + 1 }}</span>
            <div class="plan-title-readonly">
              <div class="work-title-line inline-edit-line">
                <div class="inline-title-field">
                  <ElInput v-model="planForm.title" class="inline-title-input" placeholder="请输入计划名称" />
                  <span v-if="isDuplicatePlanTitle" class="duplicate-tip">计划名称重复，请调整后再新增</span>
                </div>
                <DictSelect
                  v-model="planForm.priority"
                  class="inline-select"
                  :dict-code="RDMS_REQ_PRIORITY_DICT_CODE"
                  placeholder="优先级"
                  :clearable="false"
                />
                <ElInputNumber
                  v-model="planForm.progress"
                  class="inline-progress"
                  :min="0"
                  :max="100"
                  :step="5"
                  :precision="1"
                  controls-position="right"
                />
              </div>
            </div>
            <button class="item-remove-btn" aria-label="取消新增计划" @click="cancelInlinePlan">×</button>
          </div>
          <div class="inline-plan-actions">
            <ElButton size="small" @click="cancelInlinePlan">取消</ElButton>
            <ElButton
              size="small"
              type="primary"
              :disabled="!planForm.title.trim() || isDuplicatePlanTitle"
              @click="submitInlinePlan"
            >
              确认新增
            </ElButton>
          </div>
        </div>
      </div>
    </div>

    <div class="section">
      <div class="section-title">要点描述</div>
      <div class="single-editor">
        <div
          class="rich-editor"
          :contenteditable="!isReadonly"
          spellcheck="false"
          :data-placeholder="isReadonly ? undefined : '请输入要点描述'"
          @focus="focusEditField('keyPoints')"
          @blur="syncRichProjectField('keyPoints', $event)"
        >
          {{ projectForm.keyPoints }}
        </div>
      </div>
    </div>

    <div class="section">
      <div class="section-title">项目问题</div>
      <div class="single-editor">
        <div
          class="rich-editor"
          :contenteditable="!isReadonly"
          spellcheck="false"
          :data-placeholder="isReadonly ? undefined : '请输入项目问题'"
          @focus="focusEditField('problems')"
          @blur="syncRichProjectField('problems', $event)"
        >
          {{ projectForm.problems }}
        </div>
      </div>
    </div>

    <div v-if="!isReadonly" class="form-actions">
      <!--      <ElButton>重置表单</ElButton>-->
      <ElButton @click="emit('save')">保存草稿</ElButton>
      <ElButton type="primary" @click="emit('submit')">提交审批</ElButton>
    </div>
    <div v-else-if="scene === 'approval'" class="form-actions approval-form-actions">
      <ElButton @click="emit('back')">退出</ElButton>
      <ElButton type="primary" @click="emit('requestApprove')">审批</ElButton>
    </div>
  </div>
</template>

<style scoped>
.card {
  border: 1px solid rgba(216, 224, 232, 0.88);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.86);
  box-shadow: 0 18px 45px rgba(15, 23, 42, 0.12);
  padding-top: 20px;
}

.card-title {
  margin: 0;
  font-size: 18px;
  font-weight: 900;
}

.card-subtitle {
  margin-top: 5px;
  color: #667085;
  font-size: 12px;
}

.form-head {
  padding: 20px 64px 20px 20px;
}

.report-title {
  display: flex;
  gap: 12px;
  align-items: center;
}

.type-mark {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  border-radius: 16px;
  background: var(--el-color-primary-light-8);
  color: var(--el-color-primary);
  font-weight: 900;
}

.section {
  margin: 0 20px 18px;
  border: 1px solid #d8e0e8;
  border-radius: 16px;
  overflow: hidden;
  background: #fff;
}

.section-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 13px 16px;
  background: #f8fbfc;
  border-bottom: 1px solid #d8e0e8;
  font-weight: 900;
}

.section-title-left,
.section-title-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.source-chip {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border-radius: 999px;
  background: #f3f7f9;
  color: #475467;
  font-size: 12px;
  font-weight: 800;
}

.compose-grid {
  display: grid;
  grid-template-columns: 1.25fr 0.75fr 0.75fr 1.25fr;
  gap: 14px;
  padding: 16px;
  align-items: start;
}

.field {
  display: grid;
  gap: 6px;
}

.field label {
  color: #667085;
  font-size: 12px;
  font-weight: 800;
}

.basic-status-editor {
  display: grid;
  gap: 6px;
  padding: 0 16px 16px;
}

.basic-status-editor label {
  color: #667085;
  font-size: 12px;
  font-weight: 800;
}

.member-chips {
  height: 32px;
  min-height: 32px;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  padding: 4px 8px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background: #f5f7fa;
  box-sizing: border-box;
  overflow: hidden;
}

.member-chip {
  display: inline-flex;
  align-items: center;
  height: 20px;
  flex: 0 0 auto;
  padding: 0 8px;
  border-radius: 999px;
  background: #fff;
  color: #475467;
  font-size: 12px;
  font-weight: 800;
}

.member-chip.more {
  background: var(--el-color-primary-light-9);
  color: var(--el-color-primary);
  cursor: default;
}

.single-editor {
  padding: 16px;
}

.review-grid,
.plan-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 16px;
}

.review-grid.layout-row,
.plan-list.layout-row {
  grid-template-columns: 1fr;
}

.review-card,
.plan-card {
  display: grid;
  gap: 10px;
  padding: 12px;
  border: 1px solid #e5edf1;
  border-radius: 10px;
  background: #fff;
}

.compact-work-card {
  min-height: 58px;
  align-content: center;
  padding: 10px 12px;
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.04);
  transition:
    border-color 0.2s,
    box-shadow 0.2s,
    transform 0.2s;
}

.compact-work-card:hover {
  border-color: var(--el-color-primary-light-5);
  box-shadow: 0 8px 22px rgba(15, 23, 42, 0.08);
  transform: translateY(-1px);
}

.review-card-head,
.plan-card-head {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 28px;
  gap: 12px;
  align-items: center;
}

.review-card-head.no-remove,
.plan-card-head.no-remove {
  grid-template-columns: 28px minmax(0, 1fr);
}

.row-index {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--el-color-primary);
  color: #fff;
  font-size: 13px;
  font-weight: 900;
}

.compact-work-card .row-index {
  width: 28px;
  height: 28px;
  font-size: 13px;
}

.review-title-readonly,
.plan-title-readonly {
  display: grid;
  gap: 10px;
  align-items: center;
}

.work-title-line {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
  min-height: 30px;
  overflow: hidden;
}

.review-title-readonly strong,
.plan-title-readonly strong {
  color: #606266;
  font-size: 14px;
  font-weight: 400;
}

.compact-work-card .review-title-readonly strong,
.compact-work-card .plan-title-readonly strong {
  font-size: 14px;
  font-weight: 400;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.work-title-input {
  width: 100%;
  min-width: 0;
  flex: 1 1 160px;
  border: 0;
  border-bottom: 1px solid transparent;
  background: transparent;
  color: #606266;
  font: inherit;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.3;
  outline: none;
  overflow: hidden;
  padding: 1px 0;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.work-title-input:focus {
  border-bottom-color: var(--el-color-primary);
}

.work-title-line span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 8px;
  border-radius: 999px;
  background: #f3f7f9;
  color: #667085;
  font-size: 12px;
  font-weight: 800;
}

.work-title-line .priority-chip {
  background: #fff7ed;
  color: #c2410c;
}

.meta-chip {
  flex: 0 0 auto;
}

.item-remove-btn {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border: 1px solid #fecaca;
  border-radius: 999px;
  background: #fff;
  color: #dc2626;
  font: inherit;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.item-remove-btn:hover {
  background: #fef2f2;
}

.fixed-textarea :deep(.el-textarea__inner) {
  scrollbar-width: thin;
  scrollbar-color: #94a3b8 transparent;
}

.fixed-textarea :deep(.el-textarea__inner::-webkit-scrollbar) {
  width: 6px;
  height: 6px;
}

.fixed-textarea :deep(.el-textarea__inner::-webkit-scrollbar-track) {
  background: transparent;
}

.fixed-textarea :deep(.el-textarea__inner::-webkit-scrollbar-thumb) {
  border-radius: 999px;
  background: #94a3b8;
}

.fixed-textarea :deep(.el-textarea__inner::-webkit-scrollbar-button) {
  width: 0;
  height: 0;
  display: none;
}

.fixed-textarea :deep(.el-textarea__inner) {
  height: 86px;
  min-height: 86px;
  max-height: 86px;
  resize: none;
  overflow: auto;
  padding: 5px 11px;
  line-height: 1.6;
  white-space: pre-wrap;
}

.rich-editor {
  min-height: 86px;
  padding: 5px 11px;
  border-radius: 9px;
  outline: none;
  background: #fff;
  box-shadow: 0 0 0 1px #d8e0e8 inset;
  color: #334155;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: #94a3b8 transparent;
}

.rich-editor:hover {
  box-shadow: 0 0 0 1px #b8c4cf inset;
}

.rich-editor:focus {
  box-shadow:
    0 0 0 1px var(--el-color-primary) inset,
    0 0 0 2px var(--el-color-primary-light-8);
}

.rich-editor:empty::before {
  content: attr(data-placeholder);
  color: #98a2b3;
}

.rich-editor::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.rich-editor::-webkit-scrollbar-track {
  background: transparent;
}

.rich-editor::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: #94a3b8;
}

.rich-editor::-webkit-scrollbar-button {
  width: 0;
  height: 0;
  display: none;
}

.inline-plan-card {
  border-color: var(--el-color-primary-light-5);
  background: #f8fbfc;
}

.inline-edit-line {
  overflow: visible;
}

.inline-title-field {
  flex: 1 1 220px;
  min-width: 0;
  display: grid;
  gap: 4px;
}

.inline-title-input {
  width: 100%;
}

.inline-select {
  width: 96px;
  flex: 0 0 96px;
}

.inline-progress {
  width: 132px;
  flex: 0 0 132px;
}

.duplicate-tip {
  color: #dc2626;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.2;
}

.inline-plan-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.inline-plan-card :deep(.el-input__wrapper),
.inline-plan-card :deep(.el-select__wrapper) {
  border-radius: 9px;
  box-shadow: 0 0 0 1px #d8e0e8 inset;
}

.inline-plan-card :deep(.el-input-number__increase) {
  border-top-right-radius: 9px;
}

.inline-plan-card :deep(.el-input-number__decrease) {
  border-bottom-right-radius: 9px;
}

.inline-progress :deep(.el-input__wrapper) {
  overflow: hidden;
}

.inline-plan-card :deep(.el-input__wrapper.is-focus),
.inline-plan-card :deep(.el-select__wrapper.is-focused) {
  box-shadow:
    0 0 0 1px var(--el-color-primary) inset,
    0 0 0 2px var(--el-color-primary-light-8);
}

.form-actions {
  position: sticky;
  z-index: 5;
  bottom: 0;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: auto;
  margin-bottom: 0;
  padding: 14px 20px;
  border-top: 1px solid #d8e0e8;
  border-bottom-left-radius: 18px;
  border-bottom-right-radius: 18px;
  background: #f5f7fa;
  box-shadow: 0 -8px 18px rgba(15, 23, 42, 0.06);
}

.approval-form-actions {
  position: sticky;
  z-index: 5;
  bottom: 0;
  margin-top: auto;
  margin-bottom: 0;
  border-bottom-left-radius: 18px;
  border-bottom-right-radius: 18px;
  background: #f5f7fa;
  box-shadow: 0 -8px 18px rgba(15, 23, 42, 0.06);
}

@media (max-width: 1180px) {
  .compose-grid,
  .review-grid,
  .plan-list {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .section-title {
    align-items: flex-start;
    flex-direction: column;
  }

  .inline-edit-line {
    align-items: stretch;
    flex-direction: column;
  }

  .inline-title-field,
  .inline-select,
  .inline-progress {
    width: 100%;
    flex-basis: auto;
  }
}
</style>
