<template>
  <div class="job-detail dflex">
    <SideNav />
    <div class="job-detail__content">
      <!-- 页面标题 + Tab 切换 -->
      <JobPageHeader :activeTab="''" />
      <div class="bg-white p20 border-ra20">
        <div class="bg-main p20 border-ra20">
          <!-- 顶部操作栏 -->
          <div class="job-detail__toolbar">
            <button class="job-detail__close-btn" @click="goBack" aria-label="关闭">
              <svg viewBox="0 0 16 16" fill="none" class="job-detail__close-icon">
                <path d="M12 4L4 12M4 4l8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
              </svg>
            </button>
            <div class="job-detail__toolbar-right">
              <button class="job-detail__tool-btn" aria-label="编辑" @click="openDislikeDialog">
                <svg viewBox="0 0 16 16" fill="none" class="job-detail__tool-icon">
                  <path d="M11.5 2.5l2 2L5 13H3v-2l8.5-8.5z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>
                </svg>
              </button>
              <button class="jobs-page__action-icon-btn" :class="{ 'job-detail__tool-btn--liked': job.isFavorite }" aria-label="收藏" @click="toggleFavorite">
                <svg viewBox="0 0 16 16" :fill="job.isFavorite ? 'currentColor' : 'none'" class="job-detail__tool-icon">
                  <path d="M8 13.7l-1.1-1C3.6 9.8 1.5 7.9 1.5 5.7 1.5 3.9 2.9 2.5 4.7 2.5c1 0 2 .5 2.6 1.2h1.4c.6-.7 1.6-1.2 2.6-1.2 1.8 0 3.2 1.4 3.2 3.2 0 2.2-2.1 4.1-5.4 6.9L8 13.7z" stroke="currentColor" stroke-width="1"/>
                </svg>
              </button>
              <button class="job-detail__apply-btn" @click="handleApply">去投递</button>
            </div>
          </div>

          <!-- 内容区域（可滚动） -->
          <div class="job-detail__body">
            <!-- 导航 Tab：岗位详情 / 公司概况 -->
            <div class="job-detail__nav-tabs">
              <div
                  class="job-detail__nav-tab"
                  :class="{ 'job-detail__nav-tab--active': activeSection === 'job' }"
                  @click="activeSection = 'job'"
              >岗位详情</div>
              <div
                  class="job-detail__nav-tab"
                  :class="{ 'job-detail__nav-tab--active': activeSection === 'company' }"
                  @click="scrollToCompany"
              >公司概况</div>
              <div class="job-detail__nav-tab-right">
                <span class="job-detail__link-btn" @click="handleFeedback">问题反馈</span>
                <span class="job-detail__link-btn" @click="handleReport">原链接</span>
              </div>
            </div>

            <!-- 岗位详情内容 -->
            <template v-if="activeSection === 'job'">
              <!-- 公司 & 职位头部 -->
              <div class="job-detail__card">
                <div class="job-detail__card-top">
                  <div class="job-detail__card-left">
                    <div class="job-detail__company-row">
                      <div class="job-detail__company-icon">
                        <img v-if="job.companyLogoUrl" :src="job.companyLogoUrl" :alt="job.company" class="job-detail__company-logo-img" />
                        <svg v-else viewBox="0 0 24 24" fill="none" class="job-detail__company-svg">
                          <rect x="3" y="7" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/>
                          <path d="M7 7V5a2 2 0 012-2h6a2 2 0 012 2v2" stroke="currentColor" stroke-width="1.5"/>
                          <path d="M3 13h18" stroke="currentColor" stroke-width="1.5"/>
                        </svg>
                      </div>
                      <span class="job-detail__company-name">{{ job.company }}</span>
                    </div>
                    <h3 class="job-detail__job-title">{{ job.title }}</h3>
                    <div class="job-detail__job-meta">
                  <span class="job-detail__meta-item">
                    <svg viewBox="0 0 16 16" fill="none" class="job-detail__meta-icon">
                      <circle cx="8" cy="6.5" r="2.5" stroke="currentColor" stroke-width="1.2"/>
                      <path d="M8 14s-5-4-5-7.5a5 5 0 0110 0C13 10 8 14 8 14z" stroke="currentColor" stroke-width="1.2"/>
                    </svg>
                    {{ job.location }}
                  </span>
                      <span class="job-detail__meta-item">
                    <svg viewBox="0 0 16 16" fill="none" class="job-detail__meta-icon">
                      <rect x="2" y="3" width="12" height="11" rx="1.5" stroke="currentColor" stroke-width="1.2"/>
                      <path d="M2 6.5h12" stroke="currentColor" stroke-width="1.2"/>
                    </svg>
                    {{ job.experience }}
                  </span>
                      <span class="job-detail__meta-item">
                    <svg viewBox="0 0 16 16" fill="none" class="job-detail__meta-icon">
                      <rect x="2" y="2" width="12" height="12" rx="2" stroke="currentColor" stroke-width="1.2"/>
                      <path d="M5 8h6M8 5v6" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
                    </svg>
                    {{ job.type }}
                  </span>
                      <span v-if="job.education" class="job-detail__meta-item">
                    <svg viewBox="0 0 16 16" fill="none" class="job-detail__meta-icon">
                      <path d="M8 2L1 6l7 4 7-4-7-4z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>
                      <path d="M3 7.5v4l5 3 5-3v-4" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>
                    </svg>
                    {{ job.education }}
                  </span>
                      <span v-if="job.salary" class="job-detail__meta-item">
                    <svg viewBox="0 0 16 16" fill="none" class="job-detail__meta-icon">
                      <path d="M8 1v14M4 4h8M3 8h10M5 12h6" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
                    </svg>
                    {{ job.salary }}
                  </span>
                    </div>
                  </div>
                  <!-- 匹配度环 -->
                  <div class="job-detail__match-area">
                    <div class="job-detail__match-ring">
                      <svg viewBox="0 0 80 80" class="job-detail__ring-svg">
                        <circle cx="40" cy="40" r="34" stroke-width="5" stroke="#E8E8E8" fill="none" opacity="0.3"/>
                        <circle cx="40" cy="40" r="34" stroke-width="5" fill="none"
                                stroke="#4FC2C9"
                                stroke-linecap="round"
                                :stroke-dasharray="2 * Math.PI * 34"
                                :stroke-dashoffset="2 * Math.PI * 34 * (1 - job.matchScore / 100)"
                                transform="rotate(-90 40 40)"
                        />
                      </svg>
                      <div class="job-detail__match-score">{{ job.matchScore }}%</div>
                    </div>
                    <div class="job-detail__match-label">岗位匹配值</div>
                    <div class="job-detail__match-details">
                      <div class="job-detail__match-item" v-for="m in matchItems" :key="m.label">
                        <div class="job-detail__match-mini-ring">
                          <svg viewBox="0 0 40 40" class="job-detail__mini-ring-svg">
                            <circle cx="20" cy="20" r="16" stroke-width="3" stroke="#E8E8E8" fill="none" opacity="0.3"/>
                            <circle cx="20" cy="20" r="16" stroke-width="3" fill="none"
                                    stroke="#BFBFBF"
                                    stroke-linecap="round"
                                    :stroke-dasharray="2 * Math.PI * 16"
                                    :stroke-dashoffset="2 * Math.PI * 16 * (1 - m.score / 100)"
                                    transform="rotate(-90 20 20)"
                            />
                          </svg>
                          <span class="job-detail__mini-score">{{ m.score }}%</span>
                        </div>
                        <span class="job-detail__match-item-label">{{ m.label }}</span>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 优化简历提示 -->
              <div class="job-detail__optimize-bar">
                <span>优化简历大幅提升面试成功率！</span>
                <button class="job-detail__optimize-btn" @click="handleGenerateResume">生成岗位专属简历</button>
              </div>

              <!-- 岗位描述 -->
              <div class="job-detail__card">
                <p class="job-detail__desc-text">{{ job.companyInfo.summary }}</p>
                <div class="job-detail__tag-list">
                  <span v-for="tag in job.companyInfo.tags" :key="tag" class="job-detail__tag">{{ tag }}</span>
                </div>
              </div>

              <!-- 岗位职责 -->
              <div class="job-detail__card">
                <h3 class="job-detail__section-title">岗位职责</h3>
                <ol class="job-detail__list">
                  <li v-for="(item, i) in job.responsibilities" :key="i">{{ item }}</li>
                </ol>
              </div>

              <!-- 任职要求 -->
              <div class="job-detail__card">
                <div class="job-detail__section-header">
                  <h3 class="job-detail__section-title">任职要求</h3>
                  <span class="job-detail__skill-hint">

<!--                    深色为你拥有的技能-->
                  </span>
                </div>
                <div class="job-detail__skill-tags">

              <!-- 先不加点击选中 @click="skill.matched = !skill.matched"-->
              <span
                  v-for="skill in job.requiredSkills"
                  :key="skill.name"
                  class="job-detail__skill-tag cursor-po"
                  :class="{ 'job-detail__skill-tag--matched': skill.matched }"

              >
                {{ skill.name }}
                <svg v-if="skill.matched" viewBox="0 0 12 12" fill="none" class="job-detail__skill-close">
                  <path d="M9 3L3 9M3 3l6 6" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
                </svg>
              </span>
                </div>
                <ol class="job-detail__list">
                  <li v-for="(item, i) in job.requirements" :key="i">{{ item }}</li>
                </ol>
              </div>

              <!-- 加分项 -->
              <div class="job-detail__card">
                <h3 class="job-detail__section-title">加分项</h3>
                <p class="job-detail__desc-text">{{ job.bonus }}</p>
              </div>

              <!-- 公司概况 -->
              <div ref="companySectionRef" class="job-detail__card">
                <h3 class="job-detail__section-title">公司概况</h3>
                <div class="job-detail__company-info">
                  <div class="job-detail__company-info-left">
                    <div class="job-detail__company-header">
                      <div class="job-detail__company-logo">
                        <img v-if="job.companyLogoUrl" :src="job.companyLogoUrl" :alt="job.company" class="job-detail__company-logo-img" />
                        <svg v-else viewBox="0 0 24 24" fill="none" class="job-detail__company-svg">
                          <rect x="3" y="7" width="18" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/>
                          <path d="M7 7V5a2 2 0 012-2h6a2 2 0 012 2v2" stroke="currentColor" stroke-width="1.5"/>
                        </svg>
                      </div>
                      <span class="job-detail__company-info-name">{{ job.company }}</span>
                    </div>
                    <p class="job-detail__company-desc">{{ job.companyInfo.description }}</p>
                  </div>
                  <div class="job-detail__company-info-right pr50">
                    <div class="job-detail__company-meta-item">
                      <span class="job-detail__meta-label">成立时间：</span>
                      <span>{{ job.companyInfo.founded }}</span>
                    </div>
                    <div class="job-detail__company-meta-item">
                      <span class="job-detail__meta-label">公司地址：</span>
                      <span>{{ job.companyInfo.address }}</span>
                    </div>
                    <div class="job-detail__company-meta-item">
                      <span class="job-detail__meta-label">企业规模：</span>
                      <span>{{ job.companyInfo.size }}</span>
                    </div>
                    <div class="job-detail__company-meta-item">
                      <span class="job-detail__meta-label">官网：</span>
                      <a :href="job.companyInfo.website" target="_blank" class="job-detail__company-link">{{ job.companyInfo.website }}</a>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 融资 -->
              <div class="job-detail__card">
                <h3 class="job-detail__section-title">融资</h3>
                <p class="job-detail__desc-text">
                  <span class="job-detail__funding-label">当前融资阶段：</span>{{ job.companyInfo.fundingStage }}
                  <span class="job-detail__funding-label" style="margin-left: 0.3rem;">最新估值：</span>{{ job.companyInfo.valuation }}
                </p>
              </div>

              <!-- 最新动态 -->
              <div class="job-detail__card" v-if="job.companyInfo.news.length">
                <h3 class="job-detail__section-title">最新动态</h3>
                <div class="job-detail__news-list">
                  <div v-for="(news, i) in job.companyInfo.news" :key="i" class="job-detail__news-item">
                    <p class="job-detail__news-desc">{{ news }}</p>
                  </div>
                </div>
              </div>
            </template>

            <!-- 公司概况 Tab 已移除，点击直接滚动到岗位详情中的公司概况部分 -->
          </div>
        </div>

      </div>



    </div>
    <AiChat :job-id="jobId" />

    <!-- 职位不感兴趣反馈弹窗 -->
    <JobDislikeDialog ref="dislikeDialogRef" v-model="showDislikeDialog" :job-id="jobId" />

    <!-- 职位问题反馈弹窗 -->
    <JobFeedbackDialog ref="feedbackDialogRef" v-model="showFeedbackDialog" :job-id="jobId" />

    <!-- 岗位专属简历定制弹窗 -->
    <JobResumeCustomDialog v-model="showResumeCustomDialog" :job-info="resumeCustomJobInfo" :job-id="jobId" @skip="handleSkipToApply" />
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, nextTick, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useStore } from 'vuex'
import SideNav from '@/components/SideNav.vue'
import AiChat from '@/components/AiChat.vue'
import JobPageHeader from '@/components/JobPageHeader.vue'
import JobDislikeDialog from '@/components/JobDislikeDialog.vue'
import JobFeedbackDialog from '@/components/JobFeedbackDialog.vue'
import JobResumeCustomDialog from '@/components/JobResumeCustomDialog.vue'
import { fetchJobDetail, toggleJobFavorite, removeJobFavorite, fetchSkillGap } from '@/api/jobs'
import type { JobDetailData, SkillGapData } from '@/api/jobs'

// ==================== 路由相关 ====================

const router = useRouter()
const route = useRoute()
const store = useStore()

/** 当前岗位 ID，从路由参数中获取 */
const jobId = route.params.id as string

// ==================== 工具函数 ====================

/** 工作类型映射：数字 → 中文 */
function formatEmploymentType(type: number | undefined): string {
  const map: Record<number, string> = { 0: '全职', 1: '兼职' }
  return map[type ?? -1] ?? '未知'
}

/** 学历要求映射：数字 → 中文 */
function formatEducation(edu: number | undefined): string {
  const map: Record<number, string> = { 0: '不限', 1: '大专', 2: '本科', 3: '硕士', 4: '博士' }
  return map[edu ?? -1] ?? '未知'
}

/** 最低工作年限格式化 */
function formatExperience(min: number | undefined): string {
  if (min === undefined || min === null) return '经验不限'
  if (min === 0) return '经验不限'
  return `${min}年以上`
}

/**
 * 将带序号的文本拆分为列表项
 * 例如 "1.xxx；2.yyy；3.zzz" → ['xxx', 'yyy', 'zzz']
 */
function splitNumberedText(text: string | undefined): string[] {
  if (!text) return []
  // 按 "数字." 或 "数字、" 分割，过滤空项
  const items = text.split(/\d+[.、]/).filter((s) => s.trim())
  return items.map((s) => s.trim().replace(/[；;]$/, ''))
}

// ==================== 页面状态 ====================

/** 当前激活的内容区 Tab：job-岗位详情 / company-公司概况 */
const activeSection = ref<'job' | 'company'>('job')

/** 公司概况卡片 ref，用于滚动定位 */
const companySectionRef = ref<HTMLElement | null>(null)

/** 是否正在加载 */
const loading = ref(false)

/** 点击公司概况 tab 时，确保显示岗位详情内容并滚动到公司概况卡片 */
function scrollToCompany() {
  activeSection.value = 'job'
  nextTick(() => {
    companySectionRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' })
  })
}

// ==================== 岗位详情数据 ====================

/** 匹配度维度列表（岗位匹配环下方的子维度） */
const matchItems = ref([
  { label: '教育背景', score: 0 },
  { label: '核心技能', score: 0 },
  { label: '过往经历', score: 0 },
])

/** 技能标签项（matched 表示用户是否具备该技能，可点击切换） */
interface SkillTag {
  /** 技能名称 */
  name: string
  /** 是否匹配 */
  matched: boolean
}

/** 岗位详情响应式数据 */
const job = reactive({
  /** 岗位 ID */
  id: jobId,
  /** 公司名称（优先简称） */
  company: '',
  /** 公司 Logo URL */
  companyLogoUrl: '',
  /** 岗位标题 */
  title: '',
  /** 地区名称 */
  location: '',
  /** 工作经验要求（格式化后的文案） */
  experience: '',
  /** 工作类型（格式化后的文案） */
  type: '',
  /** 学历要求（格式化后的文案） */
  education: '',
  /** 薪资描述 */
  salary: '',
  /** 匹配总分 */
  matchScore: 0,
  /** 岗位描述（原始文本） */
  description: '',
  /** 岗位标签 */
  tags: [] as string[],
  /** 岗位职责列表（从 description 拆分） */
  responsibilities: [] as string[],
  /** 技能标签 */
  requiredSkills: [] as SkillTag[],
  /** 任职要求列表（从 requirement 拆分） */
  requirements: [] as string[],
  /** 加分项 */
  bonus: '',
  /** 来源链接 */
  sourceUrl: '',
  /** 是否已收藏 */
  isFavorite: false,
  /** 公司信息 */
  companyInfo: {
    /** 公司类型 */
    type: '',
    /** 公司所属行业 */
    industryName: '',
    /** 公司简介 */
    summary: '',
    /** 公司描述 */
    description: '',
    /** 成立时间 */
    founded: '',
    /** 公司地址 */
    address: '',
    /** 公司规模 */
    size: '',
    /** 公司官网 */
    website: '',
    /** 融资状态 */
    fundingStage: '',
    /** 最新估值 */
    valuation: '',
    /** 公司标签 */
    tags: [] as string[],
    /** 公司新闻列表 */
    news: [] as string[],
  },
})

/** 将接口返回数据填充到页面响应式对象 */
function fillJobData(data: JobDetailData) {
  job.id = data.jobId
  job.company = data.companyShortName || data.companyName || ''
  job.companyLogoUrl = data.companyLogoUrl || ''
  job.title = data.jobTitle || ''
  job.location = data.regionName || ''
  job.experience = formatExperience(data.minExperience)
  job.type = formatEmploymentType(data.employmentType)
  job.education = formatEducation(data.education)
  job.salary = data.salary || ''
  job.matchScore = data.matchScore ?? 0
  job.description = data.description || ''
  job.tags = data.tags || []
  job.sourceUrl = data.sourceUrl || ''
  job.isFavorite = data.isFavorite ?? false
  job.bonus = data.bonus || ''

  // 岗位职责：从 description 中按序号拆分
  job.responsibilities = splitNumberedText(data.description)

  // 任职要求：从 requirement 中按序号拆分
  job.requirements = splitNumberedText(data.requirement)

  // 技能标签：默认 matched 为 false
  job.requiredSkills = (data.skillTags || []).map((name) => ({ name, matched: false }))

  // 匹配度详情
  if (data.matchDetail) {
    matchItems.value = [
      { label: '教育背景', score: data.matchDetail.educationScore ?? 0 },
      { label: '核心技能', score: data.matchDetail.skillScore ?? 0 },
      { label: '过往经历', score: data.matchDetail.experienceScore ?? 0 },
    ]
  }

  // 公司信息
  job.companyInfo.type = data.companyType || ''
  job.companyInfo.industryName = data.companyIndustryName || ''
  job.companyInfo.summary = data.companySummary || ''
  job.companyInfo.description = data.companyDescription || ''
  job.companyInfo.founded = data.companyFoundedYear ? `${data.companyFoundedYear}年` : ''
  job.companyInfo.address = data.companyAddress || ''
  job.companyInfo.size = data.companyScale || ''
  job.companyInfo.website = data.companyWebsite || ''
  job.companyInfo.fundingStage = data.companyFinancingStage || ''
  job.companyInfo.valuation = data.companyLatestValuation || ''
  job.companyInfo.tags = data.companyTags || []
  job.companyInfo.news = data.companyNews || []
}

// ==================== 加载岗位详情 ====================

/** 调用接口获取岗位详情 */
async function loadJobDetail() {
  if (!jobId) return
  loading.value = true
  try {
    const res = await fetchJobDetail(jobId)
    if (res.code === '0' && res.data) {
      fillJobData(res.data)
    }
  } catch (e) {
    console.error('加载岗位详情失败', e)
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  loadJobDetail()
})

// ==================== 事件处理 ====================

/** 不感兴趣弹窗状态 */
const showDislikeDialog = ref(false)
const dislikeDialogRef = ref<InstanceType<typeof JobDislikeDialog> | null>(null)

/** 问题反馈弹窗状态 */
const showFeedbackDialog = ref(false)
const feedbackDialogRef = ref<InstanceType<typeof JobFeedbackDialog> | null>(null)

/** 打开不感兴趣弹窗 */
function openDislikeDialog() {
  dislikeDialogRef.value?.resetForm()
  showDislikeDialog.value = true
}

/** 返回职位列表页 */
function goBack() {
  // 使用 back() 回退，保证 Jobs 页能正确恢复缓存
  // 如果没有历史记录（直接访问详情页），则 push 到列表页
  if (window.history.length > 1) {
    router.back()
  } else {
    router.push('/jobs')
  }
}

/** 问题反馈 */
function handleFeedback() {
  feedbackDialogRef.value?.resetForm()
  showFeedbackDialog.value = true
}

/** 跳转到原链接 */
function handleReport() {
  if (job.sourceUrl) {
    window.open(job.sourceUrl, '_blank')
  }
}

// ==================== 岗位专属简历定制弹窗 ====================

/** 简历定制弹窗显隐 */
const showResumeCustomDialog = ref(false)

/** 技能差距分析数据 */
const skillGapData = ref<SkillGapData | null>(null)

/** 传递给简历定制弹窗的岗位信息（从 skill-gap 接口获取） */
const resumeCustomJobInfo = computed(() => ({
  title: skillGapData.value?.job?.title || job.title,
  company: job.company,
  companyLogoUrl: job.companyLogoUrl,
  location: job.location,
  matchScore: skillGapData.value?.score ?? +(job.matchScore / 10).toFixed(1),
  missingSkills: skillGapData.value?.missingSkills || [],
  keywords: skillGapData.value?.job?.skillTags || job.requiredSkills.map(s => s.name),
  sourceUrl: job.sourceUrl,
  /** 默认简历信息（来自 skill-gap 接口） */
  defaultResume: skillGapData.value?.resume || null,
}))

/** 生成岗位专属简历 — 调用 skill-gap 接口后打开定制弹窗 */
async function handleGenerateResume() {
  const loadingInstance = ElLoading.service({
    text: '正在分析岗位匹配度...',
    background: 'rgba(0, 0, 0, 0.5)',
  })
  try {
    const res = await fetchSkillGap(jobId)
    if (res.code === 0 && res.data) {
      skillGapData.value = res.data
    }
  } catch (e) {
    console.error('技能差距分析失败', e)
    ElMessage.error('分析失败，请稍后重试')
    return
  } finally {
    loadingInstance.close()
  }
  showResumeCustomDialog.value = true
}

/** 不优化直接投递 */
function handleSkipToApply() {
  if (job.sourceUrl) {
    window.open(job.sourceUrl, '_blank')
  }
}

/** 收藏/取消收藏 */
async function toggleFavorite() {
  try {
    const res = job.isFavorite
      ? await removeJobFavorite(job.id)
      : await toggleJobFavorite(job.id)
    if (res.code === '0') {
      const wasFavorite = job.isFavorite
      job.isFavorite = !job.isFavorite
      ElMessage.success(wasFavorite ? '已取消收藏' : '收藏成功')
      // 同步收藏状态到 Jobs 页面缓存，返回时无需刷新列表即可看到最新状态
      const cache = store.state.jobListCache
      if (cache) {
        const cached = cache.list.find((j: any) => j.id === job.id)
        if (cached) cached.isFavorite = job.isFavorite
      }
    }
  } catch (e) {
    console.error('收藏操作失败', e)
  }
}

/** 去投递 — 跳转到来源链接 */
function handleApply() {
  if (job.sourceUrl) {
    window.open(job.sourceUrl, '_blank')
  }
}
</script>
