<template>
  <div
    class="relative overflow-hidden bg-[radial-gradient(circle_at_12%_18%,rgba(219,95,81,0.10),transparent_24%),radial-gradient(circle_at_86%_12%,rgba(249,154,159,0.08),transparent_24%),radial-gradient(circle_at_50%_100%,rgba(222,217,178,0.06),transparent_28%),linear-gradient(180deg,#faf6ee_0%,#f9f1ef_44%,#fdf7f6_100%)]"
    :style="boxStyle">
    <div
      class="pointer-events-none absolute left-[-5rem] top-6 h-80 w-80 rounded-full bg-[rgba(219,95,81,0.20)] opacity-48 blur-[88px]">
    </div>
    <div
      class="pointer-events-none absolute right-[-5rem] top-32 h-[22rem] w-[22rem] rounded-full bg-[rgba(222,217,178,0.15)] opacity-48 blur-[88px]">
    </div>
    <div
      class="pointer-events-none absolute inset-0 opacity-14 [background-image:linear-gradient(rgba(255,255,255,0.18)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.18)_1px,transparent_1px)] [background-size:36px_36px] [mask-image:linear-gradient(180deg,rgba(0,0,0,0.8),transparent_85%)]">
    </div>

    <div class="relative z-[1] mx-auto flex h-full w-[86%] gap-6 py-5">
      <aside class="hidden w-[25rem] shrink-0 xl:block">
        <div class="sticky top-4">
          <section
            class="relative rounded-[28px] border border-white/62 bg-[linear-gradient(145deg,rgba(255,251,246,0.68),rgba(237,246,244,0.56))] p-5 shadow-[0_20px_50px_rgba(128,118,126,0.11)] backdrop-blur-[20px] after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:bg-[linear-gradient(120deg,rgba(255,255,255,0.24),transparent_45%)] after:content-['']">
            <div class="relative z-[1]">
              <h1 class="mt-2 text-[1.65rem] leading-[1.2] text-[#2c3a4a]">留下你的站点名片</h1>
              <section
                class="mt-4 rounded-[24px] border border-white/72 bg-white/58 p-4 shadow-[0_14px_32px_rgba(128,118,126,0.1)]">
                <div class="mb-3 flex items-center justify-between gap-3 text-primary">
                  <div class="flex items-center gap-2">
                    <icon-loading class="zhuan h-4 w-4" />
                    <span class="text-sm font-semibold">申请友链</span>
                  </div>
                  <span
                    class="rounded-full bg-[rgba(250,239,220,0.92)] px-2.5 py-1 text-[11px] cursor-pointer text-primary"
                    @click="fillForm">一键填入</span>
                </div>

                <n-form ref="formRef" :model="plinkData" :rules="rules" class="compact-side-form" label-placement="top"
                  require-mark-placement="right-hanging" size="small">
                  <n-form-item v-for="field in formFields" :key="field.key" :path="field.key">
                    <template #label>
                      <div class="flex items-center gap-2 text-sm font-medium text-[#72515a]">
                        <component :is="field.icon" class="h-4 w-4" />
                        {{ field.label }}
                      </div>
                    </template>
                    <n-input :value="plinkData[field.key]" :type="field.inputType"
                      :maxlength="field.maxlength" :placeholder="field.placeholder" :rows="field.rows"
                      @update:value="updateField(field.key, $event)" />
                  </n-form-item>

                  <div class="!mb-0 btn">
                    <n-button
                      class="!h-10 !w-full !rounded-full !border-none !bg-[linear-gradient(135deg,#D71A44,#DB5F51)] !text-sm !font-semibold shadow-[0_14px_28px_rgba(215,26,68,0.24)]"
                      type="primary" @click="submitPut">
                      提交友链申请
                    </n-button>
                  </div>
                </n-form>
              </section>

              <p class="mt-3 text-right text-[12px] leading-5 text-[#8a6267]">
                如果暂未显示，通常是因为还在审核中...
              </p>
            </div>
          </section>
        </div>
      </aside>

      <section
        class="min-w-0 flex-1 overflow-hidden rounded-[30px] border border-white/70 bg-transparent p-4 ring-1 ring-inset ring-[rgba(255,255,255,0.38)] shadow-[0_20px_46px_rgba(128,118,126,0.1)] sm:p-6">
        <n-scrollbar :style="contentStyle" trigger="none" class="pr-1">
          <div class="space-y-5 pr-1">


            <section class="rounded-[26px] bg-transparent p-5  sm:p-6">
              <div class="mb-5 flex items-center justify-between">
                <div>
                  <div class="text-[0.82rem] font-semibold tracking-[0.16em] text-[#718195]">已通过友链</div>
                  <h3 class="mt-2 text-[1.4rem] font-semibold text-[#5c3d46]">一起逛逛这些站点</h3>
                </div>
                <div
                  class="rounded-full border border-white/70 bg-white/42 px-4 py-2 text-sm text-[#72515a] shadow-[0_8px_18px_rgba(128,118,126,0.08)]">
                  共 {{ pList.length }} 个站点
                </div>
              </div>

              <div class="grid grid-cols-1 gap-5 md:grid-cols-2 2xl:grid-cols-3">
                <article v-for="p in pList" :key="p.pid"
                  class="cursor-pointer rounded-[26px] border border-white/72 bg-[linear-gradient(145deg,rgba(255,251,246,0.78),rgba(237,246,244,0.62))] p-6 shadow-[0_16px_34px_rgba(128,118,126,0.12)] backdrop-blur-[18px] transition-[transform,box-shadow,border-color] duration-[320ms] [transition-timing-function:cubic-bezier(0.22,1,0.36,1)] hover:-translate-y-1 hover:border-white/90 hover:shadow-[0_22px_42px_rgba(128,118,126,0.16)]"
                  @click="gotoWebsite(p.url)">
                  <div class="flex items-center gap-8">
                    <n-avatar round :size="56" :src="p.avater"
                      class="shrink-0 ring-2 ring-white/80 shadow-[0_10px_22px_rgba(128,118,126,0.14)]" />
                    <div class="min-w-0 flex-1">
                      <div
                        class="inline-flex items-center rounded-full bg-[rgba(250,239,220,0.92)] px-3 py-1 text-sm text-primary">
                        {{ p.name }}
                      </div>
                      <h4 class="mt-3 truncate text-[1.3rem] font-semibold text-[#5c3d46]">
                        {{ p.title }}
                      </h4>
                      <p class="mt-2 line-clamp-2 min-h-10 text-sm text-[#6a7a88]">
                        {{ p.desc }}
                      </p>
                    </div>
                  </div>

                  <div class="mt-5 flex flex-wrap gap-3 justify-center">
                    <div v-for="tag in getTags(p.tagname)" :key="tag" :style="{ backgroundColor: getTagColor(tag) }"
                      class="inline-flex items-center gap-1 rounded-full px-3 py-1 text-sm text-white shadow-[0_8px_20px_rgba(128,118,126,0.16)]">
                      <icon-tag2 class="h-4 w-4" />
                      {{ tag }}
                    </div>
                  </div>
                </article>
              </div>

              <div v-if="!pList.length" class="py-14 text-center text-[#8a6267]">
                暂无友链数据，等你来留下第一张站点名片。
              </div>
            </section>

            <section
              class="rounded-[26px] border border-white/66 bg-transparent p-5 ring-1 ring-inset ring-[rgba(255,255,255,0.32)] shadow-[0_16px_34px_rgba(128,118,126,0.09)] xl:hidden">
              <div class="mb-4 flex items-center gap-3 text-primary">
                <icon-loading class="zhuan h-5 w-5" />
                <span class="text-base font-semibold">申请友链</span>
              </div>

              <n-form ref="mobileFormRef" :model="plinkData" :rules="rules" label-placement="top"
                require-mark-placement="right-hanging">
                <n-form-item v-for="field in formFields" :key="field.key" :path="field.key">
                  <template #label>
                    <div class="flex items-center gap-2 text-sm font-medium text-[#72515a]">
                      <component :is="field.icon" class="h-4 w-4" />
                      {{ field.label }}
                    </div>
                  </template>
                  <n-input :value="plinkData[field.key]" :type="field.inputType" :rows="field.rows"
                    :maxlength="field.maxlength" :placeholder="field.placeholder"
                    @update:value="updateField(field.key, $event)" />
                </n-form-item>

                <n-form-item class="btn">
                  <n-button
                    class="!h-11 !w-full !rounded-full !border-none !bg-[linear-gradient(135deg,#D71A44,#DB5F51)] !font-semibold shadow-[0_14px_28px_rgba(215,26,68,0.24)]"
                    type="primary" @click="submitPut">
                    提交友链申请
                  </n-button>
                </n-form-item>
              </n-form>
            </section>
          </div>
        </n-scrollbar>
      </section>
    </div>
  </div>
</template>

<script setup lang="ts">
import avaIcon from '@/icon/plink/ava.svg'
import descIcon from '@/icon/plink/desc.svg'
import siteIcon from '@/icon/plink/site.svg'
import tagIcon from '@/icon/plink/tag.svg'
import urlIcon from '@/icon/plink/uri.svg'
import userIcon from '@/icon/plink/user.svg'
import type { FormInst, FormRules } from 'naive-ui'
import type { Component } from 'vue'

definePage({
  name: 'plink',
  meta: {
    title: '友链',
  }
})

interface PlinkFormData {
  name: string
  title: string
  avater: string
  url: string
  desc: string
  tagname: string
}

interface PlinkItem {
  pid: string | number
  name: string
  title: string
  avater: string
  url: string
  desc: string
  tagname: string
}

interface PlinkListResponse {
  data: PlinkItem[]
}

interface TagColorItem {
  tag: string
  color: string
}

interface UserCookieInfo {
  nickname?: string
  ava_url?: string
}

type PlinkFieldKey = keyof PlinkFormData

interface PlinkFormField {
  key: PlinkFieldKey
  label: string
  placeholder: string
  icon: Component | string
  inputType?: 'text' | 'textarea'
  maxlength?: number
  rows?: number
}

const SOFT_TAG_PALETTE = [
  '#d46a7c',
  '#c97956',
  '#b9894d',
  '#6f9d86',
  '#5d92a8',
  '#7d88b8',
  '#9a78b5',
  '#8f7d6b',
  '#c86b8f',
  '#cf7f6a',
  '#a98f55',
  '#7aa37b',
  '#5d9f95',
  '#6d8fc7',
  '#8a80c4',
  '#a16fa1',
  '#b67b67',
  '#927f72',
  '#6f8b5f',
  '#4f8aa8',
  '#7a96a1',
  '#b38754',
  '#a66767',
  '#7b6aa8',
] as const

const TEXTAREA_AUTOSIZE = {
  minRows: 1,
  maxRows: 2,
} as const

const formFields: PlinkFormField[] = [
  {
    key: 'name',
    label: '昵称',
    placeholder: '请输入你的昵称',
    icon: userIcon,
    inputType: 'text',
  },
  {
    key: 'title',
    label: '网站名称',
    placeholder: '请输入你的网站名称',
    icon: siteIcon,
    inputType: 'text',
  },
  {
    key: 'url',
    label: '站点地址',
    placeholder: '请输入你的网站地址',
    icon: urlIcon,
    inputType: 'text',
  },
  {
    key: 'avater',
    label: '头像链接',
    placeholder: '请输入你的头像链接',
    icon: avaIcon,
    inputType: 'text',
  },
  {
    key: 'desc',
    label: '站点介绍',
    placeholder: '请用一句话简短描述你的站点',
    icon: descIcon,
    inputType: 'textarea',
    maxlength: 50,
    rows:2
  },
  {
    key: 'tagname',
    label: '标签',
    placeholder: '用逗号隔开，每个标签最多 4 个字，只显示前 3 个',
    icon: tagIcon,
    inputType: 'textarea',
    maxlength: 50,
    rows:2
  },
]

const boxStyle = ref<Record<string, string>>({})
const contentStyle = ref<Record<string, string>>({})
const screenWidth = ref(typeof window === 'undefined' ? 0 : window.innerWidth)
const nav = $store.nav.useNavStore() as { navH: number }
const formRef = ref<FormInst | null>(null)
const mobileFormRef = ref<FormInst | null>(null)
const pList = ref<PlinkItem[]>([])
const tagColorList = ref<TagColorItem[]>([])

const plinkData = reactive<PlinkFormData>({
  name: '',
  title: '',
  avater: '',
  url: '',
  desc: '',
  tagname: '',
})

const rules: FormRules = {
  name: [{ required: true, message: '昵称不能为空', trigger: ['blur'] }],
  title: [{ required: true, message: '网站名称不能为空', trigger: ['blur'] }],
  url: [{ required: true, message: '站点地址不能为空', trigger: ['blur'] }],
  avater: [{ required: true, message: '头像链接不能为空', trigger: ['blur'] }],
  desc: [{ required: true, message: '站点介绍不能为空', trigger: ['blur'] }],
  tagname: [{ required: true, message: '标签不能为空', trigger: ['blur'] }],
}

function updateLayout() {
  const viewportHeight = window.innerHeight - nav.navH - 1
  screenWidth.value = window.innerWidth
  boxStyle.value = { height: `${viewportHeight}px` }
  contentStyle.value = { height: `${Math.max(viewportHeight - 48, 280)}px` }
}

function updateField(key: PlinkFieldKey, value: string) {
  plinkData[key] = value
}

function normalizeTag(tag: string) {
  return tag.trim().slice(0, 4)
}

function getTags(str: string) {
  const normalized = (str || '').replace(/，/g, ',')
  return normalized.split(',').slice(0, 3).map(normalizeTag).filter(Boolean)
}

function buildTagColorMap(tags: string[]): TagColorItem[] {
  return tags.map((tag, index) => ({
    tag,
    color: SOFT_TAG_PALETTE[index % SOFT_TAG_PALETTE.length],
  }))
}

function getTagColor(tag: string) {
  return tagColorList.value.find((item) => item.tag === tag)?.color || SOFT_TAG_PALETTE[0]
}

async function getPlinkList() {
  try {
    const res = await $http.plink.getPlinkList() as PlinkListResponse
    const uniqueTags = Array.from(new Set(res.data.flatMap((item) => getTags(item.tagname))))
    tagColorList.value = buildTagColorMap(uniqueTags)
    pList.value = res.data
  } catch {
    pList.value = []
  }
}

function gotoWebsite(url: string) {
  if (!url) return
  window.open(url, '_blank')
}

function resetFormData() {
  plinkData.name = ''
  plinkData.title = ''
  plinkData.avater = ''
  plinkData.url = ''
  plinkData.desc = ''
  plinkData.tagname = ''
}

function fillForm() {
  const token = $cookies.get('token')
  if (!token) {
    $msg.warning('请先登录后再一键填入')
    return
  }

  const userinfo = ($cookies.get('userinfo') || {}) as UserCookieInfo
  plinkData.name = userinfo.nickname || ''
  plinkData.avater = userinfo.ava_url || ''
}

function getActiveForm() {
  if (screenWidth.value >= 1280) return formRef.value || mobileFormRef.value
  return mobileFormRef.value || formRef.value
}

async function submitPut() {
  const activeForm = getActiveForm()
  if (!activeForm) return

  try {
    await activeForm.validate()
  } catch {
    $msg.error('请先完善表单内容')
    return
  }

  try {
    const res = await $http.plink.addPlink(plinkData)
    if (res?.code !== 200) {
      $msg.error(res.msg)
      return
    }

    $msg.success(res.msg)
    resetFormData()
    await getPlinkList()
  } catch {
    $msg.error('提交失败，请稍后再试')
  }
}

onMounted(() => {
  updateLayout()
  void getPlinkList()
  window.addEventListener('resize', updateLayout)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', updateLayout)
})
</script>

<style scoped lang="less">
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.zhuan {
  animation: spin 1.5s linear infinite;
}

:deep(.n-form-item) {
  grid-template-rows: unset !important;
}

:deep(.btn.n-form-item) {
  .n-form-item-feedback-wrapper {
    display: none !important;
  }
}

:deep(.compact-side-form .n-input) {
  --n-height: 38px !important;
}

:deep(.n-form-item-feedback__line) {
  text-align: right;
  font-size: 12px !important;
  color: #8b96a3;
}

:deep(.n-input),
:deep(.n-input .n-input-wrapper),
:deep(.n-input .n-input__textarea) {
  background: rgba(255, 255, 255, 0.72) !important;
  border-radius: 18px !important;
}

:deep(.n-input) {
  --n-border: 1px solid rgba(214, 224, 226, 0.92) !important;
  --n-border-hover: 1px solid rgba(190, 206, 214, 0.98) !important;
  --n-border-focus: 1px solid rgba(236, 102, 171, 0.52) !important;
  --n-box-shadow-focus: 0 0 0 4px rgba(236, 102, 171, 0.1) !important;
}

:deep(.n-input__input-el),
:deep(.n-input__textarea-el) {
  color: #314155 !important;
}

:deep(.n-input__placeholder) {
  color: #95a3b2 !important;
}

:deep(.n-input__placeholder) {
  font-size: 13px;

  span {
    font-size: 13px;
  }
}

:deep(.n-form-item-feedback__line) {
  color: red;
}
</style>
