<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { Check, Plus, Refresh } from '@element-plus/icons-vue'
import http, { apiErrorMessage } from '../api/http'
import { useAuthStore } from '../stores/auth'
import { academicTermLabel, academicTermOptionClass, defaultAcademicTermId } from '../utils/academicTerms'

const auth = useAuthStore()
const isManager = computed(() =>
  auth.user?.roles.some(r => ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin'].includes(r)) ?? false)
const isTeacher = computed(() => auth.user?.roles.includes('Teacher') && !isManager.value)

const adjustments = ref<any[]>([])
const pendingReviews = ref<any[]>([])
const loading = ref(false)
const reviewLoading = ref(false)
const dialog = ref(false)
const rejectDialog = ref(false)
const currentAdj = ref<any>(null)
const rejectComment = ref('')
const terms = ref<any[]>([])
const tasks = ref<any[]>([])
const sessionOptions = ref<any[]>([])
const classrooms = ref<any[]>([])
const periods = ref<any[]>([])
const sessionTask = ref<any>(null)
const sessionLoading = ref(false)
const termId = ref<string>()
const tab = ref(isManager.value ? 'reviews' : 'mine')
const minePage = ref(1)
const mineTotal = ref(0)
const reviewPage = ref(1)
const reviewTotal = ref(0)
const pageSize = 20

const form = reactive({
  teachingTaskId: undefined as string | undefined,
  sourceKey: undefined as string | undefined,
  sourceScheduleEntryId: undefined as string | undefined,
  sourceWeek: undefined as number | undefined,
  type: 'Reschedule' as string,
  reason: '',
  submit: true,
  targetDate: '' as string,
  dayOfWeek: undefined as number | undefined,
  startPeriod: undefined as number | undefined,
  periodCount: 2,
  classroomId: undefined as string | undefined,
  substituteTeacherId: undefined as string | undefined,
  cancelWeek: undefined as number | undefined,
  cancelDate: '' as string,
})

const typeLabels: Record<string, string> = { Reschedule: '调课', Cancel: '停课', Makeup: '补课', Substitute: '代课' }
const statusLabels: Record<string, string> = { Draft: '草稿', Submitted: '待审核', Approved: '已通过', Rejected: '已退回' }
const statusColors: Record<string, 'info' | 'warning' | 'success' | 'danger'> = { Draft: 'info', Submitted: 'warning', Approved: 'success', Rejected: 'danger' }
const sourceRequired = computed(() => ['Reschedule', 'Cancel', 'Makeup'].includes(form.type))
const selectedSession = computed(() =>
  sessionOptions.value.find(item => sessionKey(item) === form.sourceKey))

function periodOptions() {
  if (periods.value.length) {
    return periods.value.map(item => ({
      value: item.periodNumber,
      label: `第 ${item.periodNumber} 节 · ${item.name} ${item.startsAt}–${item.endsAt}`,
    }))
  }
  return Array.from({ length: 12 }, (_, i) => ({ value: i + 1, label: `第 ${i + 1} 节` }))
}

function sessionKey(session: any) {
  return `${session.scheduleEntryId}:${session.week}`
}

function weekdayLabel(day: number) {
  return ['','一','二','三','四','五','六','日'][day]
}

function sessionLabel(session: any) {
  const end = session.startPeriod + session.periodCount - 1
  const room = session.classroomName
    ? ` · ${session.buildingName ?? ''}${session.classroomName}`
    : ' · 无固定教室'
  return `第 ${session.week} 周 · ${session.date} 周${weekdayLabel(session.dayOfWeek)} · 第 ${session.startPeriod}–${end} 节${room}`
}

async function load(resetPages = false) {
  if (resetPages) {
    minePage.value = 1
    reviewPage.value = 1
  }
  loading.value = true
  reviewLoading.value = isManager.value
  try {
    if (isTeacher.value || (!isManager.value)) {
      const response = await http.get('/course-adjustments/mine', {
        params: { academicTermId: termId.value, page: minePage.value, pageSize },
      })
      adjustments.value = response.data.items
      mineTotal.value = response.data.total
    }
    if (isManager.value) {
      const response = await http.get('/course-adjustments/pending-reviews', {
        params: { academicTermId: termId.value, page: reviewPage.value, pageSize },
      })
      pendingReviews.value = response.data.items
      reviewTotal.value = response.data.total
    }
  } catch (e) { ElMessage.error(apiErrorMessage(e)) }
  finally { loading.value = false; reviewLoading.value = false }
}

function openCreate() {
  Object.assign(form, {
    teachingTaskId: undefined,
    sourceKey: undefined,
    sourceScheduleEntryId: undefined,
    sourceWeek: undefined,
    type: 'Reschedule',
    reason: '',
    submit: true,
    targetDate: '',
    dayOfWeek: undefined,
    startPeriod: undefined,
    periodCount: 2,
    classroomId: undefined,
    substituteTeacherId: undefined,
    cancelWeek: undefined,
    cancelDate: '',
  })
  dialog.value = true
}

async function loadSessionOptions() {
  sessionOptions.value = []
  classrooms.value = []
  periods.value = []
  sessionTask.value = null
  form.sourceKey = undefined
  form.sourceScheduleEntryId = undefined
  form.sourceWeek = undefined
  if (!form.teachingTaskId) return
  sessionLoading.value = true
  try {
    const data = (await http.get(
      `/course-adjustments/tasks/${form.teachingTaskId}/session-options`,
    )).data
    sessionTask.value = data.task
    sessionOptions.value = data.sessions
    classrooms.value = data.classrooms
    periods.value = data.periods
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    sessionLoading.value = false
  }
}

function selectSession() {
  const session = selectedSession.value
  if (!session) return
  form.sourceScheduleEntryId = session.scheduleEntryId
  form.sourceWeek = session.week
  form.periodCount = session.periodCount
  form.classroomId = session.classroomId ?? undefined
}

async function submit() {
  if (!form.teachingTaskId) { ElMessage.warning('请选择教学班'); return }
  if (sourceRequired.value && !selectedSession.value) { ElMessage.warning('请选择要处理的原课次'); return }
  if (selectedSession.value?.hasExistingAdjustment) { ElMessage.warning('该课次已有调停课记录，请选择其他课次'); return }
  if (['Reschedule', 'Makeup'].includes(form.type) && !form.targetDate) { ElMessage.warning('请选择目标日期'); return }
  if (['Reschedule', 'Makeup'].includes(form.type) && !form.startPeriod) { ElMessage.warning('请选择目标节次'); return }
  if (!form.reason.trim()) { ElMessage.warning('请填写申请原因'); return }
  try {
    await http.post('/course-adjustments', {
      ...form,
      sourceKey: undefined,
      dayOfWeek: form.dayOfWeek || null,
      startPeriod: form.startPeriod || null,
      classroomId: form.classroomId || null,
      substituteTeacherId: form.substituteTeacherId || null,
      cancelWeek: form.cancelWeek || null,
      targetDate: form.targetDate || null,
      cancelDate: form.cancelDate || null,
    })
    dialog.value = false
    ElMessage.success('申请已提交')
    await load()
  } catch (e) { ElMessage.error(apiErrorMessage(e)) }
}

async function loadTaskOptions() {
  if (!isTeacher.value && isManager.value) return
  try {
    tasks.value = (await http.get('/course-adjustments/task-options', {
      params: { academicTermId: termId.value || undefined },
    })).data
  } catch (error) {
    tasks.value = []
    ElMessage.error(apiErrorMessage(error))
  }
}

async function doSubmit(adj: any) {
  try {
    await http.post(`/course-adjustments/${adj.id}/submit`)
    ElMessage.success('已提交审核')
    await load()
  } catch (e) { ElMessage.error(apiErrorMessage(e)) }
}

async function doApprove(adj: any) {
  try {
    await http.post(`/course-adjustments/${adj.id}/approve`)
    ElMessage.success('已通过')
    await load()
  } catch (e) { ElMessage.error(apiErrorMessage(e)) }
}

function openReject(adj: any) {
  currentAdj.value = adj
  rejectComment.value = ''
  rejectDialog.value = true
}

async function doReject() {
  if (!currentAdj.value) return
  try {
    await http.post(`/course-adjustments/${currentAdj.value.id}/reject`, {
      comment: rejectComment.value,
    })
    rejectDialog.value = false
    ElMessage.success('已退回')
    await load()
  } catch (e) { ElMessage.error(apiErrorMessage(e)) }
}

onMounted(async () => {
  try {
    const termRes = await http.get('/base-data/terms')
    terms.value = termRes.data
    termId.value = defaultAcademicTermId(terms.value)
    await loadTaskOptions()
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
  await load()
})

function changeType() {
  form.targetDate = ''
  form.startPeriod = undefined
  form.classroomId = selectedSession.value?.classroomId ?? undefined
}
function showTarget(type: string) {
  return type === 'Reschedule' || type === 'Makeup'
}
function showSub(type: string) { return type === 'Substitute' }
</script>

<template>
  <div class="page-stack adj-page">
    <section class="page-intro">
      <div>
        <span class="section-kicker">COURSE ADJUSTMENT</span>
        <h2>调停课管理</h2>
        <p>教师提交调课、停课、补课、代课申请，学院审核后生效并通知相关人员。</p>
      </div>
      <div style="display:flex;gap:8px;align-items:center">
        <el-button v-if="isTeacher" type="primary" :icon="Plus" @click="openCreate">提交申请</el-button>
        <el-button :icon="Refresh" @click="() => load()">刷新</el-button>
      </div>
    </section>

    <section class="adj-toolbar">
      <el-select v-model="termId" clearable placeholder="全部学期" @change="() => { load(true); loadTaskOptions() }">
        <el-option v-for="t in terms" :key="t.id" :label="academicTermLabel(t)" :value="t.id" :class="academicTermOptionClass(t)" />
      </el-select>
      <el-segmented v-model="tab" :options="[
        ...(isTeacher ? [{ label: '我的申请', value: 'mine' }] : []),
        ...(isManager ? [{ label: '待审核', value: 'reviews' }] : []),
      ]" />
    </section>

    <!-- My applications -->
    <section v-if="tab === 'mine'" v-loading="loading" class="adj-list">
      <article v-for="adj in adjustments" :key="adj.id" class="adj-card" :class="adj.status.toLowerCase()">
        <header>
          <div>
            <span>{{ adj.courseCode }} · {{ adj.taskNumber }}</span>
            <h3>{{ adj.courseName }}</h3>
            <p>{{ adj.teacherNames.join('、') }} · {{ adj.collegeName }}</p>
          </div>
          <div class="adj-tags">
            <el-tag :type="adj.type === 'Reschedule' ? 'primary' : adj.type === 'Cancel' ? 'danger' : adj.type === 'Makeup' ? 'success' : 'warning'" size="small">
              {{ typeLabels[adj.type] }}
            </el-tag>
            <el-tag :type="statusColors[adj.status]" size="small">{{ statusLabels[adj.status] }}</el-tag>
          </div>
        </header>
        <div class="adj-body">
          <p v-if="adj.reason"><b>原因：</b>{{ adj.reason }}</p>
          <div v-if="adj.sourceDate" class="adjustment-route">
            <div><small>原课次</small><b>第 {{ adj.sourceWeek }} 周 · {{ adj.sourceDate }} · 第 {{ adj.sourceStartPeriod }}–{{ adj.sourceStartPeriod + adj.sourcePeriodCount - 1 }} 节</b><span>{{ adj.sourceClassroomName || '无固定教室' }}</span></div>
            <i>{{ adj.type === 'Cancel' ? '×' : '→' }}</i>
            <div v-if="adj.type !== 'Cancel'"><small>{{ adj.type === 'Makeup' ? '新增补课' : '调整至' }}</small><b>{{ adj.targetDate }} · 第 {{ adj.startPeriod }}–{{ adj.startPeriod + adj.periodCount - 1 }} 节</b><span>{{ adj.classroomName ? `${adj.buildingName} ${adj.classroomName}` : adj.sourceClassroomName || '无固定教室' }}</span></div>
            <div v-else><small>处理结果</small><b>仅停掉本次课程</b><span>其他周次保持不变</span></div>
          </div>
          <div class="adj-details">
            <span v-if="!adj.sourceDate && adj.targetDate"><b>日期：</b>{{ adj.targetDate }}</span>
            <span v-if="!adj.sourceDate && adj.dayOfWeek"><b>星期：</b>周{{ weekdayLabel(adj.dayOfWeek) }}</span>
            <span v-if="!adj.sourceDate && adj.startPeriod"><b>节次：</b>第{{ adj.startPeriod }}–{{ adj.startPeriod + adj.periodCount - 1 }}节</span>
            <span v-if="!adj.sourceDate && adj.cancelWeek"><b>停课周次：</b>第{{ adj.cancelWeek }}周</span>
            <span v-if="adj.substituteTeacherName"><b>代课教师：</b>{{ adj.substituteTeacherName }}</span>
          </div>
          <el-alert v-if="adj.reviewComment" :title="`审核意见：${adj.reviewComment}`" type="warning" :closable="false" show-icon />
        </div>
        <footer v-if="adj.status === 'Draft'">
          <el-button size="small" type="primary" @click="doSubmit(adj)">提交审核</el-button>
        </footer>
      </article>
      <el-empty v-if="!adjustments.length" description="暂无调停课申请" />
      <el-pagination
        v-if="mineTotal > pageSize"
        v-model:current-page="minePage"
        :page-size="pageSize"
        :total="mineTotal"
        layout="total, prev, pager, next"
        class="table-pagination"
        @current-change="() => load()"
      />
    </section>

    <!-- Pending reviews -->
    <section v-if="tab === 'reviews'" v-loading="reviewLoading" class="adj-list">
      <article v-for="adj in pendingReviews" :key="adj.id" class="adj-card review">
        <header>
          <div>
            <span>{{ adj.courseCode }} · {{ adj.taskNumber }}</span>
            <h3>{{ adj.courseName }}</h3>
            <p>{{ adj.teacherNames.join('、') }} · {{ adj.collegeName }}</p>
          </div>
          <el-tag :type="adj.type === 'Reschedule' ? 'primary' : adj.type === 'Cancel' ? 'danger' : adj.type === 'Makeup' ? 'success' : 'warning'" size="small">
            {{ typeLabels[adj.type] }}
          </el-tag>
        </header>
        <div class="adj-body">
          <p><b>原因：</b>{{ adj.reason }}</p>
          <div v-if="adj.sourceDate" class="adjustment-route">
            <div><small>原课次</small><b>第 {{ adj.sourceWeek }} 周 · {{ adj.sourceDate }} · 第 {{ adj.sourceStartPeriod }}–{{ adj.sourceStartPeriod + adj.sourcePeriodCount - 1 }} 节</b><span>{{ adj.sourceClassroomName || '无固定教室' }}</span></div>
            <i>{{ adj.type === 'Cancel' ? '×' : '→' }}</i>
            <div v-if="adj.type !== 'Cancel'"><small>{{ adj.type === 'Makeup' ? '新增补课' : '调整至' }}</small><b>{{ adj.targetDate }} · 第 {{ adj.startPeriod }}–{{ adj.startPeriod + adj.periodCount - 1 }} 节</b><span>{{ adj.classroomName ? `${adj.buildingName} ${adj.classroomName}` : adj.sourceClassroomName || '无固定教室' }}</span></div>
            <div v-else><small>处理结果</small><b>仅停掉本次课程</b><span>其他周次保持不变</span></div>
          </div>
          <div class="adj-details">
            <span v-if="!adj.sourceDate && adj.targetDate"><b>日期：</b>{{ adj.targetDate }}</span>
            <span v-if="!adj.sourceDate && adj.dayOfWeek"><b>星期：</b>周{{ weekdayLabel(adj.dayOfWeek) }}</span>
            <span v-if="!adj.sourceDate && adj.startPeriod"><b>节次：</b>第{{ adj.startPeriod }}–{{ adj.startPeriod + adj.periodCount - 1 }}节</span>
            <span v-if="!adj.sourceDate && adj.cancelWeek"><b>停课周次：</b>第{{ adj.cancelWeek }}周</span>
            <span v-if="adj.substituteTeacherName"><b>代课教师：</b>{{ adj.substituteTeacherName }}</span>
          </div>
          <p class="adj-meta"><b>提交时间：</b>{{ new Date(adj.submittedAt).toLocaleString('zh-CN') }}</p>
        </div>
        <footer>
          <el-button size="small" type="danger" plain @click="openReject(adj)">退回</el-button>
          <el-button size="small" type="success" :icon="Check" @click="doApprove(adj)">通过</el-button>
        </footer>
      </article>
      <el-empty v-if="!pendingReviews.length" description="暂无待审核申请" />
      <el-pagination
        v-if="reviewTotal > pageSize"
        v-model:current-page="reviewPage"
        :page-size="pageSize"
        :total="reviewTotal"
        layout="total, prev, pager, next"
        class="table-pagination"
        @current-change="() => load()"
      />
    </section>

    <!-- Create dialog -->
    <el-dialog v-model="dialog" title="发起单次课程调整" width="760px" top="4vh" class="adjustment-dialog">
      <el-form label-position="top" class="adjustment-form">
        <section class="adjustment-step">
          <header><b>1</b><div><h3>选择业务类型</h3><p>每次申请只处理一个具体课次。</p></div></header>
          <el-form-item label="申请类型" required>
            <el-segmented v-model="form.type" :options="[
              { label: '调课', value: 'Reschedule' },
              { label: '停课', value: 'Cancel' },
              { label: '补课', value: 'Makeup' },
              { label: '代课', value: 'Substitute' },
            ]" @change="changeType" />
          </el-form-item>
          <el-alert
            :title="form.type === 'Reschedule' ? '把原课次移到另一个日期和节次，原时间不再上课。' : form.type === 'Cancel' ? '只停掉选中的这一次课，不影响其他周次。' : form.type === 'Makeup' ? '保留原课次，另外增加一次补课。' : '为教学班增加代课教师。'"
            type="info" :closable="false"
          />
        </section>

        <section class="adjustment-step">
          <header><b>2</b><div><h3>锁定原课次</h3><p>从已发布课表中选择，不再手填周次和星期。</p></div></header>
          <el-form-item label="教学班" required>
            <el-select v-model="form.teachingTaskId" filterable placeholder="选择本人承担的教学班" @change="loadSessionOptions">
              <el-option v-for="t in tasks" :key="t.id" :label="`${t.taskNumber} · ${t.courseName}`" :value="t.id" />
            </el-select>
          </el-form-item>
          <el-form-item v-if="sourceRequired" label="原课次" required>
            <el-select
              v-model="form.sourceKey" filterable :loading="sessionLoading"
              placeholder="选择第几周、哪一天、哪一节课" @change="selectSession"
            >
              <el-option
                v-for="session in sessionOptions" :key="sessionKey(session)"
                :label="sessionLabel(session)" :value="sessionKey(session)"
                :disabled="session.hasExistingAdjustment"
              >
                <span>{{ sessionLabel(session) }}</span>
                <small v-if="session.hasExistingAdjustment" class="session-used">已有申请</small>
              </el-option>
            </el-select>
          </el-form-item>
          <el-empty v-if="form.teachingTaskId && sourceRequired && !sessionLoading && !sessionOptions.length" description="该教学班没有可用的已发布课次" :image-size="56" />
        </section>

        <section v-if="showTarget(form.type)" class="adjustment-step target-step">
          <header><b>3</b><div><h3>{{ form.type === 'Reschedule' ? '安排调课后课次' : '安排补课课次' }}</h3><p>课程时长沿用原课次，系统会在审批时检查教师、班级和教室冲突。</p></div></header>
          <div class="source-target-strip" v-if="selectedSession">
            <div><span>原课次</span><strong>{{ sessionLabel(selectedSession) }}</strong></div>
            <i>→</i>
            <div><span>目标课次</span><strong>{{ form.targetDate || '待选日期' }} · {{ form.startPeriod ? `第 ${form.startPeriod} 节起` : '待选节次' }}</strong></div>
          </div>
          <div class="form-grid two">
            <el-form-item label="目标日期" required>
              <el-date-picker
                v-model="form.targetDate" type="date" value-format="YYYY-MM-DD"
                :disabled-date="(date: Date) => sessionTask && (date < new Date(`${sessionTask.termStartDate}T00:00:00`) || date > new Date(`${sessionTask.termEndDate}T23:59:59`))"
                placeholder="选择本学期内日期"
              />
            </el-form-item>
            <el-form-item label="目标起始节次" required>
              <el-select v-model="form.startPeriod" placeholder="选择节次">
                <el-option v-for="o in periodOptions()" :key="o.value" :label="o.label" :value="o.value" />
              </el-select>
            </el-form-item>
          </div>
          <el-form-item label="目标教室">
            <el-select v-model="form.classroomId" clearable filterable placeholder="留空则沿用原教室">
              <el-option
                v-for="room in classrooms" :key="room.id"
                :label="`${room.campusName} · ${room.buildingName} ${room.name} · ${room.capacity} 人`"
                :value="room.id"
              />
            </el-select>
          </el-form-item>
        </section>

        <template v-if="showSub(form.type)">
          <section class="adjustment-step">
            <header><b>3</b><div><h3>选择代课教师</h3><p>代课教师必须为在职教师。</p></div></header>
            <el-form-item label="代课教师" required>
              <el-select v-model="form.substituteTeacherId" filterable placeholder="选择代课教师" />
            </el-form-item>
          </section>
        </template>

        <el-form-item label="申请原因" required class="reason-field">
          <el-input v-model="form.reason" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请详细说明调停课原因" />
        </el-form-item>
        <el-form-item>
          <el-checkbox v-model="form.submit">提交后直接送审</el-checkbox>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialog = false">取消</el-button>
        <el-button type="primary" @click="submit">提交申请</el-button>
      </template>
    </el-dialog>

    <!-- Reject dialog -->
    <el-dialog v-model="rejectDialog" title="退回申请" width="500px">
      <el-form label-position="top">
        <el-form-item label="退回意见">
          <el-input v-model="rejectComment" type="textarea" :rows="3" maxlength="500" show-word-limit placeholder="请说明退回原因" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="rejectDialog = false">取消</el-button>
        <el-button type="danger" @click="doReject">确认退回</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.adj-toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.adj-list { display: grid; gap: 12px; }
.adj-card { background: #fff; border: 1px solid #e4e7ed; border-radius: 8px; padding: 16px 20px; }
.adj-card header { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.adj-card header h3 { font-size: 15px; margin: 4px 0; }
.adj-card header p { font-size: 12px; color: var(--muted); margin: 0; }
.adj-card header span { font-size: 11px; color: var(--muted); text-transform: uppercase; }
.adj-tags { display: flex; gap: 6px; flex-shrink: 0; }
.adj-body { margin: 12px 0; font-size: 13px; }
.adj-details { display: flex; flex-wrap: wrap; gap: 4px 16px; color: var(--muted); font-size: 12px; margin-top: 8px; }
.adj-meta { font-size: 11px; color: var(--muted); margin-top: 8px; }
.adj-card footer { display: flex; justify-content: flex-end; gap: 8px; border-top: 1px solid #ebeef5; padding-top: 12px; }
.adj-card.review { border-left: 4px solid #e6a23c; }
.adj-card.draft { border-left: 4px solid #909399; }
.adj-card.submitted { border-left: 4px solid #e6a23c; }
.adj-card.approved { border-left: 4px solid #67c23a; }
.adj-card.rejected { border-left: 4px solid #f56c6c; }
.adjustment-route {
  display: grid; grid-template-columns: minmax(0, 1fr) 34px minmax(0, 1fr);
  align-items: stretch; gap: 8px; margin: 12px 0; padding: 10px;
  background: #f4f7f9; border: 1px solid #dfe7eb;
}
.adjustment-route > div { display: grid; gap: 4px; padding: 9px 11px; background: white; border-left: 3px solid var(--teal); }
.adjustment-route small { color: var(--muted); font-size: 10px; }
.adjustment-route b { font-size: 12px; color: var(--ink); }
.adjustment-route span { color: var(--muted); font-size: 11px; }
.adjustment-route > i { align-self: center; color: var(--indigo); font: 700 20px/1 Consolas, monospace; text-align: center; }
.adjustment-form { display: grid; gap: 14px; }
.adjustment-step { padding: 16px; border: 1px solid var(--line); background: #fbfcfd; }
.adjustment-step > header { display: flex; align-items: flex-start; gap: 11px; margin-bottom: 14px; }
.adjustment-step > header > b {
  display: grid; place-items: center; width: 26px; height: 26px; flex: 0 0 26px;
  color: white; background: var(--indigo); font: 700 12px/1 Consolas, monospace;
}
.adjustment-step > header h3 { margin: 1px 0 3px; font-size: 14px; }
.adjustment-step > header p { margin: 0; color: var(--muted); font-size: 11px; }
.adjustment-step .el-form-item:last-child { margin-bottom: 0; }
.target-step { border-color: #b9d9d4; background: #f4faf8; }
.source-target-strip { display: grid; grid-template-columns: 1fr 34px 1fr; align-items: stretch; gap: 8px; margin-bottom: 14px; }
.source-target-strip > div { display: grid; gap: 5px; padding: 11px; background: white; border: 1px solid #d9e3e6; }
.source-target-strip span { color: var(--muted); font-size: 10px; }
.source-target-strip strong { font-size: 11px; line-height: 1.55; }
.source-target-strip > i { align-self: center; color: var(--teal); font: 700 20px/1 Consolas, monospace; text-align: center; }
.session-used { float: right; color: #b34e48; }
.reason-field { padding: 14px 16px 0; border-top: 1px solid var(--line); }
@media (max-width: 680px) {
  .adjustment-route, .source-target-strip { grid-template-columns: 1fr; }
  .adjustment-route > i, .source-target-strip > i { transform: rotate(90deg); padding: 2px; }
  .adjustment-step { padding: 13px; }
}

</style>
