#import "theme.typ": *
#import "config.typ": *

#let icon-map-pin = image("../assets/icons/map-pin.svg")
#let icon-phone = image("../assets/icons/phone.svg")
#let icon-mail = image("../assets/icons/mail.svg")
#let icon-globe = image("../assets/icons/globe.svg")

#let profile-photo = if profile.photo-path != "" {
  image(profile.photo-path, width: 100%, height: 100%, fit: "cover")
} else {
  none
}

#let profile-photo-frame(content) = {
  if content != none {
    box(width: 100%, height: 100%, clip: true, content)
  } else {
    rect(
      width: 100%,
      height: 100%,
      fill: color-bar-bg,
      stroke: stroke-placeholder,
    )[
      #align(center + horizon)[
        #text(fill: color-muted, size: size-body)[照片]
      ]
    ]
  }
}

/// 左上 / 右下装饰条（通过 page foreground 绘制，每页自动出现）
#let page-corners-layer() = box(width: page-paper-width, height: page-paper-height)[
  #place(
    top + left,
    dx: corner-bar-inset-x,
    dy: corner-bar-inset-y,
    block(width: corner-bar-width, height: corner-bar-height, fill: color-skill-bar),
  )
  #place(
    bottom + right,
    dx: -corner-bar-inset-x,
    dy: -corner-bar-inset-y,
    block(width: corner-bar-width, height: corner-bar-height, fill: color-skill-bar),
  )
]

/// 页眉：姓名 + 职位 + 简介 + 2 寸照片
#let hero-section() = block(width: 100%, below: space-none)[
  #grid(
    columns: (1fr, photo-width),
    column-gutter: space-hero-to-photo,
    align: (top, top),
    [
      #text(font: heading-font, size: size-name, weight: "bold", fill: color-ink)[#profile.name]
      #v(space-hero-name-gap)
      #text(font: heading-font, size: size-heading, weight: "bold", fill: color-accent-bright)[#profile.title]
      #v(space-hero-title-gap)
      #set text(weight: "regular")
      #set par(leading: leading-summary, spacing: space-none, justify: true)
      #text(fill: color-text-light, size: size-summary)[#profile.summary]
    ],
    [
      #align(right)[
        #box(width: photo-width, height: photo-height, clip: true, stroke: stroke-photo)[
          #profile-photo-frame(profile-photo)
        ]
      ]
    ],
  )
]

/// 页眉与正文之间的横线
#let header-divider() = block(width: 100%, above: space-block, below: space-block)[
  #line(length: 100%, stroke: stroke-divider)
]

/// 分栏标题
#let section-title(title, sidebar: false, divider: false, above: auto, below: auto) = {
  let title-above = if above != auto {
    above
  } else if sidebar {
    space-none
  } else {
    space-main-section
  }
  let title-below = if below != auto {
    below
  } else if sidebar {
    space-title-gap
  } else {
    space-main-title-below
  }
  block(width: 100%, above: title-above, below: title-below)[
    #text(font: heading-font, size: size-heading, weight: "bold", fill: color-ink)[#title]
    #if divider [
      #v(space-inline)
      #line(length: 100%, stroke: stroke-divider)
    ]
  ]
}

/// 侧栏区块分隔线
#let sidebar-section-divider() = block(width: 100%, above: space-block, below: space-block)[
  #line(length: 100%, stroke: stroke-divider)
]

#let contact-line(icon, body) = block(below: space-inline)[
  #grid(
    columns: (icon-column-width, 1fr),
    column-gutter: space-micro,
    align: (center + horizon, left),
    box(width: icon-box-size, height: icon-box-size, baseline: 0.08em, icon),
    text(fill: color-body, size: size-secondary)[#body],
  )
]

#let contact-block() = block(above: space-none)[
  #contact-line(icon-map-pin, contact.address)
  #contact-line(icon-phone, link("tel:" + contact.phone, contact.phone))
  #contact-line(icon-mail, link("mailto:" + contact.email, contact.email))
  #if contact.website != "" {
    contact-line(icon-globe, link(contact.website, contact.website-label))
  }
]

/// 教育背景条目（notes 可选，一段普通正文）
#let edu-entry(degree, school, period, location, notes: "") = block(above: space-none, below: space-none)[
  #text(fill: color-body, size: size-body)[#degree]
  #v(space-edu-meta-gap)
  #text(fill: color-text-light, size: size-secondary)[
    #school#if period != "" [ · #period]#if location != "" [ · #location]
  ]
  #if notes != "" [
    #v(space-edu-notes-before)
    #set par(leading: leading-edu-notes, spacing: space-none, justify: true)
    #text(fill: color-text-light, size: size-secondary)[#notes]
  ]
]

#let education-block(show-notes: false) = {
  for (i, item) in education.enumerate() {
    if i > 0 {
      v(space-between-entries)
    }
    edu-entry(
      item.degree,
      item.school,
      item.period,
      item.location,
      notes: if show-notes { item.at("notes", default: "") } else { "" },
    )
  }
}

/// 侧栏技能补充列表（skills.notes 为空则不渲染）
#let skill-notes-block() = {
  if skills.notes.len() > 0 {
    block(above: space-none)[
      #set text(fill: color-text-light, size: size-secondary)
      #set par(leading: list-item-leading, spacing: space-none, justify: true)
      #set list(
        tight: true,
        indent: list-indent,
        body-indent: list-body-indent,
      )
      #for line in skills.notes [
        - #line
      ]
    ]
  }
}

/// 侧栏技能子标题
#let sidebar-subtitle(title, above: auto, below: auto) = {
  let gap-above = if above != auto { above } else { space-inline }
  let gap-below = if below != auto { below } else { space-subtitle-gap }
  block(above: gap-above, below: gap-below)[
    #text(font: heading-font, size: size-body, fill: color-body)[#title]
  ]
}

/// 技能进度条（level: 0–1）；config 提供 abilities / language 时由 abilities-block 渲染
#let skill-bar(name, level, subtitle: none, above: space-none) = block(above: above, below: space-none)[
  #if subtitle != none [
    #grid(
      columns: (1fr, auto),
      align: horizon,
      text(fill: color-text-light, size: size-secondary)[#name],
      text(fill: color-text-light, size: size-secondary)[#subtitle],
    )
  ] else [
    #text(fill: color-text-light, size: size-secondary)[#name]
  ]
  #v(space-inline)
  #box(width: 100%, height: skill-bar-height, radius: skill-bar-radius, clip: true)[
    #place(left + top, block(width: 100%, height: skill-bar-height, fill: color-bar-bg))
    #place(left + top, block(width: level * 100%, height: skill-bar-height, fill: color-skill-bar))
  ]
]

#let has-abilities-section() = {
  let ability-list = skills.at("abilities", default: ())
  let has-lang = skills.at("language", default: none) != none
  ability-list.len() > 0 or has-lang
}

/// 「能力」进度条区块（skills.abilities / skills.language 有数据时才显示）
#let abilities-block() = {
  if has-abilities-section() {
    sidebar-subtitle("能力", above: space-none)
    block(below: space-none)[
      #for (i, item) in skills.at("abilities", default: ()).enumerate() {
        skill-bar(
          item.name,
          item.level,
          above: if i == 0 { space-none } else { space-skill-gap },
        )
      }
      #let lang = skills.at("language", default: none)
      #if lang != none {
        skill-bar(
          lang.name,
          lang.level,
          subtitle: lang.at("label", default: none),
          above: if skills.at("abilities", default: ()).len() == 0 {
            space-none
          } else {
            space-skill-gap
          },
        )
      }
    ]
  }
}

#let has-skill-groups() = skills.at("groups", default: ()).len() > 0

#let skill-groups-block() = {
  for (i, group) in skills.at("groups", default: ()).enumerate() {
    sidebar-subtitle(
      group.title,
      above: if i == 0 and not has-abilities-section() { space-none } else { space-subsection-gap },
    )
    block(below: space-none)[
      #set par(leading: list-item-leading, spacing: space-none, justify: true)
      #text(fill: color-text-light, size: size-secondary)[#group.items]
    ]
  }
}

#let tech-pill(label) = box(
  fill: color-page,
  stroke: stroke-pill,
  radius: pill-radius,
  inset: (x: pill-inset-x, y: pill-inset-y),
  baseline: 0.15em,
  text(fill: color-text-light, size: size-secondary)[#label],
)

#let tech-stack-block() = block(width: 100%, above: space-none, below: space-inline)[
  #box(width: 100%)[
    #set par(spacing: pill-gap, leading: leading-pill-wrap)
    #for (i, tag) in skills.tags.enumerate() [
      #if i > 0 [#h(pill-gap)]
      #tech-pill(tag)
    ]
  ]
]

#let skills-section-block() = {
  abilities-block()
  if has-skill-groups() {
    skill-groups-block()
  } else {
    sidebar-subtitle(
      "技术栈",
      above: if has-abilities-section() { space-subsection-gap } else { space-none },
    )
    tech-stack-block()
  }
  if skills.notes.len() > 0 {
    sidebar-subtitle("补充", above: space-subsection-gap)
    skill-notes-block()
  }
}

/// 主栏经历 / 项目条目
#let timeline-entry(entry, title-key: "company", subtitle-key: "role") = block[
  #block(above: space-entry-title-above, below: space-entry-title-below)[
    #text(fill: color-body, size: size-body, weight: "bold")[
      #if subtitle-key != none [
        #entry.at(title-key) / #entry.at(subtitle-key)
      ] else [
        #entry.at(title-key)
      ]
    ]
  ]
  #text(fill: color-text-light, size: size-body)[
    #entry.location#if entry.location != "" [，]#entry.start - #entry.end
  ]
  #let intro = entry.at("intro", default: "")
  #if intro != "" [
    #v(space-body)
    #set par(leading: list-item-leading, spacing: space-none, justify: true)
    #text(weight: "regular", fill: color-text-light, size: size-body)[#intro]
  ]
  #v(space-body)
  #set text(weight: "regular", fill: color-text-light, size: size-body)
  #set par(leading: list-item-leading, spacing: space-none, justify: true)
  #set list(
    tight: true,
    indent: list-indent,
    body-indent: list-body-indent,
  )
  #for line in entry.bullets [
    - #line
  ]
]

#let project-entry(entry) = timeline-entry(entry, title-key: "name", subtitle-key: "org")
#let experience-entry(entry) = timeline-entry(entry, title-key: "company", subtitle-key: "role")

#let experiences-block() = {
  for (i, entry) in experiences.enumerate() {
    if i > 0 { v(space-between-entries) }
    experience-entry(entry)
  }
}

#let projects-block() = {
  for (i, entry) in projects.enumerate() {
    if i > 0 { v(space-between-entries) }
    project-entry(entry)
  }
}

/// 获奖经历条目（bullets 可留空）
#let award-entry(entry) = block[
  #block(above: space-entry-title-above, below: space-entry-title-below)[
    #text(fill: color-body, size: size-body, weight: "bold")[#entry.title]
  ]
  #text(fill: color-text-light, size: size-body)[#entry.meta]
  #if entry.bullets.len() > 0 [
    #v(space-body)
    #set text(weight: "regular", fill: color-text-light, size: size-body)
    #set par(leading: list-item-leading, spacing: space-none, justify: true)
    #set list(
      tight: true,
      indent: list-indent,
      body-indent: list-body-indent,
    )
    #for line in entry.bullets [
      - #line
    ]
  ]
]

#let awards-block() = {
  for (i, entry) in awards.enumerate() {
    if i > 0 { v(space-between-entries) }
    award-entry(entry)
  }
}

#let research-block() = {
  if research != "" {
    block(above: space-none)[
      #set par(leading: leading-body, spacing: space-none, justify: true)
      #text(fill: color-text-light, size: size-body)[#research]
    ]
  }
}

#let publication-entry(entry, index) = block(above: space-none, below: space-none)[
  #if index > 1 { v(space-between-entries) }
  #text(fill: color-body, size: size-secondary, weight: "bold")[
    \[#index\] #entry.title
  ]
  #v(space-inline)
  #text(fill: color-text-light, size: size-secondary)[#entry.authors]
  #v(space-micro)
  #text(fill: color-text-light, size: size-secondary)[#entry.venue]
]

#let publications-block() = {
  for (i, entry) in publications.enumerate() {
    publication-entry(entry, i + 1)
  }
}
