<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";
import {
  Bell,
  CirclePlus,
  Filter,
  Headset,
  Refresh,
  Search,
} from "@element-plus/icons-vue";

import {
  defaultHomeAnnouncements,
  defaultHomeBanners,
  fetchMobileHomeConfig,
  type HomeBannerSlide,
} from "@/api/homeConfig";
import {
  emptyListingPublishOptions,
  type ListingPublishOptions,
} from "@/api/listingOptions";
import { fetchListings, type Listing } from "@/api/listings";
import {
  formatHafCoinM,
  getCoinM,
  getCoinWan,
  getListingChips,
  getListingDisplayPrice,
  getListingSubtitle,
  getListingTitle,
  getLoginMethod,
  getServerRegion,
  hasGiftResources,
} from "@/views/mobile/listingDisplay";

const loading = ref(false);
const listings = ref<Listing[]>([]);
const announcements = ref<string[]>(defaultHomeAnnouncements);
const banners = ref<HomeBannerSlide[]>(defaultHomeBanners);
const publishOptions = ref<ListingPublishOptions>(emptyListingPublishOptions);
const filters = reactive({
  keyword: "",
  server: "",
  loginMethod: "",
  rank: "",
  minCoin: undefined as number | undefined,
  maxPrice: undefined as number | undefined,
});
const sortBy = ref("recommended");

const serverOptions = computed(() =>
  uniqueOptions(
    publishOptions.value.server_options
      .map((item) => item.trim())
      .filter(Boolean)
  )
);
const loginMethodOptions = computed(() =>
  uniqueOptions(
    publishOptions.value.login_method_options
      .map((item) => item.trim())
      .filter(Boolean)
  )
);

const visibleListings = computed(() => {
  const keyword = filters.keyword.trim().toLowerCase();
  const filtered = listings.value.filter((item) => {
    const text = [
      item.title,
      item.description,
      item.rank_level,
      getServerRegion(item),
      getLoginMethod(item),
      getListingTitle(item),
    ]
      .join(" ")
      .toLowerCase();
    if (keyword && !text.includes(keyword)) return false;
    if (filters.server && getServerRegion(item) !== filters.server) return false;
    if (filters.loginMethod && getLoginMethod(item) !== filters.loginMethod) return false;
    if (filters.rank && item.rank_level !== filters.rank) return false;
    if (filters.minCoin && getCoinM(item) < filters.minCoin) return false;
    if (filters.maxPrice && getListingDisplayPrice(item) > filters.maxPrice) return false;
    return true;
  });

  return [...filtered].sort((a, b) => {
    if (sortBy.value === "priceAsc") {
      return getListingDisplayPrice(a) - getListingDisplayPrice(b);
    }
    if (sortBy.value === "priceDesc") {
      return getListingDisplayPrice(b) - getListingDisplayPrice(a);
    }
    if (sortBy.value === "coinDesc") {
      return getCoinWan(b) - getCoinWan(a);
    }
    const bTime = Date.parse(b.published_at || b.created_at || "") || 0;
    const aTime = Date.parse(a.published_at || a.created_at || "") || 0;
    return getCoinWan(b) - getCoinWan(a) || bTime - aTime;
  });
});

const statCards = computed(() => [
  { label: "可租账号", value: `${visibleListings.value.length}`, hint: "当前筛选结果" },
  {
    label: "高哈夫币",
    value: `${listings.value.filter((item) => getCoinM(item) >= 100).length}`,
    hint: "100M 以上",
  },
  {
    label: "账密登录",
    value: `${listings.value.filter((item) => getLoginMethod(item) === "账号密码").length}`,
    hint: "交接更快",
  },
]);

onMounted(loadHome);

async function loadHome() {
  loading.value = true;
  try {
    const [nextListings, config] = await Promise.all([
      fetchListings(),
      fetchMobileHomeConfig(),
    ]);
    listings.value = nextListings;
    announcements.value = config.announcements;
    banners.value = config.banners;
    publishOptions.value = config.publish_options;
  } catch {
    announcements.value = defaultHomeAnnouncements;
    banners.value = defaultHomeBanners;
    publishOptions.value = emptyListingPublishOptions;
  } finally {
    loading.value = false;
  }
}

function resetFilters() {
  filters.keyword = "";
  filters.server = "";
  filters.loginMethod = "";
  filters.rank = "";
  filters.minCoin = undefined;
  filters.maxPrice = undefined;
  sortBy.value = "recommended";
}

function uniqueOptions(values: string[]) {
  return [...new Set(values.map((item) => item.trim()).filter(Boolean))];
}
</script>

<template>
  <section class="pc-home-redesign">
    <div class="home-head">
      <div class="brand-block">
        <span class="brand-mark-large">锤</span>
        <div>
          <strong>大锤商行</strong>
          <small>三角洲行动哈夫币租号</small>
        </div>
      </div>
      <div class="home-searchbar">
        <el-icon><Search /></el-icon>
        <input v-model="filters.keyword" placeholder="搜区服 / 段位 / 哈夫币 / 皮肤" />
      </div>
      <RouterLink class="home-service" to="/notifications">
        <el-icon><Headset /></el-icon>
        <span>客服</span>
      </RouterLink>
      <RouterLink class="home-publish" to="/seller/listings/create">
        <el-icon><CirclePlus /></el-icon>
        <span>发布账号</span>
      </RouterLink>
    </div>

    <div class="home-announcement">
      <el-icon><Bell /></el-icon>
      <el-carousel
        height="22px"
        direction="vertical"
        indicator-position="none"
        :autoplay="true"
        :interval="3200"
      >
        <el-carousel-item v-for="item in announcements" :key="item">
          <span>{{ item }}</span>
        </el-carousel-item>
      </el-carousel>
    </div>

    <section class="home-grid">
      <aside class="filter-panel-pc">
        <div class="panel-title">
          <div>
            <strong>筛选</strong>
            <span>{{ visibleListings.length }} 个结果</span>
          </div>
          <el-button :icon="Refresh" link @click="resetFilters">重置</el-button>
        </div>

        <label>
          <span>区服</span>
          <el-select v-model="filters.server" clearable placeholder="全部区服">
            <el-option v-for="item in serverOptions" :key="item" :label="item" :value="item" />
          </el-select>
        </label>
        <label>
          <span>上号方式</span>
          <el-select v-model="filters.loginMethod" clearable placeholder="全部方式">
            <el-option v-for="item in loginMethodOptions" :key="item" :label="item" :value="item" />
          </el-select>
        </label>
        <label>
          <span>段位</span>
          <el-select v-model="filters.rank" clearable placeholder="全部段位">
            <el-option
              v-for="item in publishOptions.rank_options"
              :key="item"
              :label="item"
              :value="item"
            />
          </el-select>
        </label>
        <label>
          <span>最低哈夫币</span>
          <el-input-number
            v-model="filters.minCoin"
            :min="0"
            :step="50"
            class="full-control"
            placeholder="单位 M"
          />
        </label>
        <label>
          <span>最高价格</span>
          <el-input-number
            v-model="filters.maxPrice"
            :min="0"
            :step="50"
            class="full-control"
            placeholder="单位 元"
          />
        </label>

        <div class="quick-chip-group">
          <button type="button" @click="filters.minCoin = 100">100M+</button>
          <button type="button" @click="filters.minCoin = 300">300M+</button>
          <button type="button" @click="filters.loginMethod = '账号密码'">账密优先</button>
          <button type="button" @click="filters.server = 'QQ'">QQ 区服</button>
        </div>
      </aside>

      <main class="home-main">
        <section class="hero-board">
          <el-carousel height="210px" indicator-position="outside" :interval="3600">
            <el-carousel-item v-for="slide in banners" :key="slide.title || slide.image_url">
              <div
                class="hero-slide"
                :class="[`tone-${slide.tone}`, { 'has-image': slide.image_url }]"
              >
                <img
                  v-if="slide.image_url"
                  :src="slide.image_url"
                  :alt="slide.title || slide.eyebrow || '首页轮播'"
                />
                <div class="hero-copy">
                  <span v-if="slide.eyebrow">{{ slide.eyebrow }}</span>
                  <h1 v-if="slide.title">{{ slide.title }}</h1>
                  <p v-if="slide.pill">{{ slide.pill }}</p>
                </div>
                <em v-if="slide.badge">{{ slide.badge }}</em>
              </div>
            </el-carousel-item>
          </el-carousel>
        </section>

        <div class="home-stats">
          <div v-for="item in statCards" :key="item.label">
            <strong>{{ item.value }}</strong>
            <span>{{ item.label }}</span>
            <small>{{ item.hint }}</small>
          </div>
        </div>

        <div class="list-head">
          <div>
            <p class="eyebrow">Account Market</p>
            <h2>可租账号</h2>
          </div>
          <div class="list-actions">
            <el-radio-group v-model="sortBy" size="small">
              <el-radio-button label="recommended">综合</el-radio-button>
              <el-radio-button label="coinDesc">哈夫币</el-radio-button>
              <el-radio-button label="priceAsc">低价</el-radio-button>
              <el-radio-button label="priceDesc">高价</el-radio-button>
            </el-radio-group>
            <RouterLink class="all-link" to="/listings">
              <el-icon><Filter /></el-icon>
              全部账号
            </RouterLink>
          </div>
        </div>

        <el-empty
          v-if="!loading && visibleListings.length === 0"
          description="没有符合条件的账号"
        />
        <div v-else v-loading="loading" class="desktop-list">
          <RouterLink
            v-for="item in visibleListings.slice(0, 8)"
            :key="item.id"
            class="desktop-card"
            :to="`/listings/${item.id}`"
          >
            <div class="desktop-cover">
              <img
                v-if="item.cover_url"
                :src="item.cover_url"
                :alt="getListingTitle(item)"
              />
              <span v-else>HFB</span>
              <em v-if="hasGiftResources(item)">有赠送</em>
            </div>
            <div class="desktop-info">
              <div class="desktop-title">
                <strong>{{ getListingTitle(item) }}</strong>
              </div>
              <p>{{ getListingSubtitle(item) || item.description || "平台担保交接，资料以截图为准。" }}</p>
              <div class="desktop-tags">
                <span>{{ getServerRegion(item) }}</span>
                <span>{{ getLoginMethod(item) }}</span>
                <span>{{ item.rank_level || "未填写段位" }}</span>
                <span
                  v-for="chip in getListingChips(item).slice(0, 4)"
                  :key="`${item.id}-${chip.label}`"
                >
                  {{ chip.label }}:{{ chip.value }}
                </span>
              </div>
            </div>
            <div class="desktop-price">
              <strong>¥{{ getListingDisplayPrice(item) }}</strong>
              <span>押金 ¥{{ item.deposit_amount }}</span>
              <small>{{ formatHafCoinM(getCoinWan(item)) }}</small>
            </div>
          </RouterLink>
        </div>
      </main>
    </section>
  </section>
</template>

<style scoped>
.pc-home-redesign {
  display: grid;
  gap: 16px;
}

.home-head,
.home-announcement,
.filter-panel-pc,
.hero-board,
.home-stats > div,
.desktop-card {
  border: 1px solid #e8edf3;
  border-radius: 12px;
  background: #ffffff;
  box-shadow: 0 10px 28px rgba(23, 35, 61, 0.05);
}

.home-head {
  display: grid;
  grid-template-columns: auto minmax(260px, 1fr) auto auto;
  gap: 12px;
  align-items: center;
  padding: 14px;
}

.brand-block,
.home-searchbar,
.home-service,
.home-publish,
.home-announcement,
.panel-title,
.list-head,
.list-actions,
.desktop-tags {
  display: flex;
  align-items: center;
}

.brand-block {
  gap: 10px;
}

.brand-mark-large {
  display: grid;
  width: 40px;
  height: 40px;
  place-items: center;
  border-radius: 12px;
  background: #fff3e8;
  color: #ff6a00;
  font-weight: 900;
}

.brand-block strong,
.brand-block small {
  display: block;
}

.brand-block strong {
  color: #17233d;
  font-size: 16px;
}

.brand-block small {
  margin-top: 2px;
  color: #7b8798;
  font-size: 12px;
}

.home-searchbar {
  gap: 9px;
  height: 42px;
  border: 1px solid #edf1f6;
  border-radius: 999px;
  background: #f7f9fc;
  padding: 0 14px;
  color: #7b8798;
}

.home-searchbar input {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: #17233d;
  font-size: 14px;
}

.home-service,
.home-publish,
.all-link {
  justify-content: center;
  gap: 6px;
  min-height: 40px;
  border-radius: 999px;
  padding: 0 14px;
  font-weight: 800;
}

.home-service,
.all-link {
  border: 1px solid #e8edf3;
  color: #1477ff;
}

.home-publish {
  background: #ff6a00;
  color: #ffffff;
}

.home-announcement {
  gap: 10px;
  padding: 10px 14px;
  color: #7a4b00;
}

.home-announcement :deep(.el-carousel) {
  flex: 1;
  min-width: 0;
}

.home-announcement span {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-grid {
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.filter-panel-pc {
  position: sticky;
  top: 92px;
  display: grid;
  gap: 14px;
  padding: 16px;
}

.panel-title {
  justify-content: space-between;
}

.panel-title strong,
.panel-title span,
.filter-panel-pc label > span {
  display: block;
}

.panel-title strong {
  color: #17233d;
  font-size: 18px;
}

.panel-title span {
  margin-top: 3px;
  color: #7b8798;
  font-size: 12px;
}

.filter-panel-pc label > span {
  margin-bottom: 7px;
  color: #536173;
  font-size: 13px;
  font-weight: 700;
}

.quick-chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.quick-chip-group button {
  border: 0;
  border-radius: 999px;
  background: #f3f6fa;
  color: #536173;
  padding: 7px 10px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 700;
}

.home-main {
  display: grid;
  gap: 14px;
}

.hero-board {
  overflow: hidden;
  padding: 0;
}

.hero-board :deep(.el-carousel__indicators--outside) {
  margin-top: 4px;
}

.hero-slide {
  position: relative;
  display: flex;
  min-height: 210px;
  overflow: hidden;
  border-radius: 12px;
  background: linear-gradient(135deg, #ffffff 0%, #eef6ff 100%);
  padding: 26px;
}

.hero-slide.tone-green {
  background: linear-gradient(135deg, #ffffff 0%, #effcf4 100%);
}

.hero-slide.tone-orange {
  background: linear-gradient(135deg, #ffffff 0%, #fff4e8 100%);
}

.hero-slide.has-image {
  align-items: flex-end;
  color: #ffffff;
}

.hero-slide img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-slide.has-image::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(90deg, rgba(10, 18, 32, 0.68), rgba(10, 18, 32, 0.12));
}

.hero-copy {
  position: relative;
  z-index: 1;
  max-width: 680px;
}

.hero-copy span {
  color: #1477ff;
  font-size: 13px;
  font-weight: 900;
}

.hero-slide.has-image .hero-copy span,
.hero-slide.has-image .hero-copy h1,
.hero-slide.has-image .hero-copy p {
  color: #ffffff;
}

.hero-copy h1 {
  margin: 8px 0 0;
  color: #17233d;
  font-size: 34px;
  line-height: 1.18;
}

.hero-copy p {
  display: inline-flex;
  margin: 16px 0 0;
  border-radius: 999px;
  background: #ffefb5;
  color: #7a4b00;
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 800;
}

.hero-slide > em {
  position: absolute;
  top: 20px;
  right: 22px;
  z-index: 1;
  border-radius: 12px;
  background: #ff6a00;
  color: #ffffff;
  padding: 8px 10px;
  font-style: normal;
  font-weight: 900;
}

.home-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.home-stats > div {
  display: grid;
  gap: 4px;
  padding: 16px;
}

.home-stats strong {
  color: #1477ff;
  font-size: 26px;
}

.home-stats span {
  color: #17233d;
  font-weight: 800;
}

.home-stats small {
  color: #7b8798;
}

.list-head {
  justify-content: space-between;
  margin-top: 4px;
}

.list-head h2,
.list-head p {
  margin: 0;
}

.list-actions {
  gap: 10px;
}

.desktop-list {
  display: grid;
  gap: 12px;
}

.desktop-card {
  display: grid;
  grid-template-columns: 146px minmax(0, 1fr) 132px;
  gap: 16px;
  align-items: stretch;
  padding: 12px;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.desktop-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 36px rgba(23, 35, 61, 0.1);
}

.desktop-cover {
  position: relative;
  display: grid;
  min-height: 112px;
  place-items: center;
  overflow: hidden;
  border-radius: 10px;
  background: #17233d;
  color: #ffffff;
  font-weight: 900;
}

.desktop-cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.desktop-cover em {
  position: absolute;
  top: 8px;
  right: 8px;
  border-radius: 999px;
  background: #ff6a00;
  color: #ffffff;
  padding: 4px 7px;
  font-size: 11px;
  font-style: normal;
  font-weight: 800;
}

.desktop-info {
  min-width: 0;
  padding: 4px 0;
}

.desktop-title strong {
  display: block;
  overflow: hidden;
  color: #17233d;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 17px;
}

.desktop-info p {
  margin: 8px 0 0;
  color: #64748b;
  font-size: 13px;
}

.desktop-tags {
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 13px;
}

.desktop-tags span {
  border-radius: 999px;
  background: #f3f6fa;
  color: #536173;
  padding: 5px 9px;
  font-size: 12px;
}

.desktop-price {
  display: grid;
  align-content: center;
  justify-items: end;
  border-left: 1px solid #edf1f6;
  color: #7b8798;
  padding-left: 14px;
}

.desktop-price strong {
  color: #ef4444;
  font-size: 26px;
}

.desktop-price span,
.desktop-price small {
  margin-top: 4px;
}

@media (max-width: 1120px) {
  .home-head {
    grid-template-columns: 1fr 1fr;
  }

  .home-grid {
    grid-template-columns: 1fr;
  }

  .filter-panel-pc {
    position: static;
  }
}
</style>
