import {
  AFFINITY_PROGRESS_MARKERS,
  AFFINITY_PROGRESS_MAX,
  AFFINITY_PROGRESS_MIN,
  getAffinityLevelMeta,
} from '../data/affinityLevels';

type AffinityProgressMarker = (typeof AFFINITY_PROGRESS_MARKERS)[number];

function clamp(value: number, min: number, max: number) {
  return Math.min(max, Math.max(min, value));
}

function getNextAffinityMarker(affinity: number) {
  const currentLevel = getAffinityLevelMeta(affinity);
  if (currentLevel.nextAffinity == null) return null;

  return (
    AFFINITY_PROGRESS_MARKERS.find(
      (marker) => marker.value === currentLevel.nextAffinity,
    ) ?? null
  );
}

function getAffinityProgressRatio(value: number) {
  return clamp(
    (value - AFFINITY_PROGRESS_MIN) /
      (AFFINITY_PROGRESS_MAX - AFFINITY_PROGRESS_MIN),
    0,
    1,
  );
}

function getAnchorTransform(ratio: number) {
  if (ratio <= 0.02) return 'translateX(0)';
  if (ratio >= 0.98) return 'translateX(-100%)';
  return 'translateX(-50%)';
}

function isMarkerReached(marker: AffinityProgressMarker, affinity: number) {
  if (marker.value < 0) {
    return affinity < 0;
  }

  return affinity >= marker.value;
}

export function AffinityStatusCard({ affinity }: { affinity: number }) {
  const currentLevel = getAffinityLevelMeta(affinity);
  const nextLevel = getNextAffinityMarker(affinity);
  const currentRatio = getAffinityProgressRatio(affinity);
  const zeroRatio = getAffinityProgressRatio(0);
  const activeMarkerValue =
    currentLevel.minAffinity <= AFFINITY_PROGRESS_MIN
      ? AFFINITY_PROGRESS_MIN
      : currentLevel.minAffinity;
  const fillLeftRatio = Math.min(currentRatio, zeroRatio);
  const fillWidthRatio = Math.abs(currentRatio - zeroRatio);
  const fillWidthPercent =
    fillWidthRatio > 0 ? `${Math.max(fillWidthRatio * 100, 1)}%` : '0%';
  const currentPointerTone =
    affinity < 0
      ? 'border-rose-100/90 bg-rose-300 shadow-[0_0_16px_rgba(251,113,133,0.45)]'
      : 'border-sky-50/90 bg-sky-300 shadow-[0_0_18px_rgba(125,211,252,0.35)]';
  const fillGradient =
    affinity < 0
      ? 'linear-gradient(90deg, rgba(251,113,133,0.92) 0%, rgba(253,164,175,0.98) 100%)'
      : 'linear-gradient(90deg, rgba(125,211,252,0.92) 0%, rgba(251,191,36,0.94) 60%, rgba(251,113,133,0.96) 100%)';

  return (
    <div className="space-y-3">
      <div className="rounded-xl border border-white/8 bg-black/20 px-4 py-3">
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <div className="text-[10px] tracking-[0.18em] text-zinc-500">
              好感等级
            </div>
            <div className="mt-2 flex flex-wrap items-center gap-2">
              <span
                className={`rounded-full border px-2.5 py-1 text-[10px] tracking-[0.16em] ${currentLevel.accentClassName}`}
              >
                {currentLevel.label}
              </span>
              <span className="text-sm font-semibold text-white">
                当前好感 {affinity}
              </span>
            </div>
          </div>

          <div className="text-right text-[10px] tracking-[0.16em] text-zinc-500">
            {nextLevel ? (
              <>
                <div>下一节点</div>
                <div className="mt-1 text-zinc-200">
                  {nextLevel.label} · {nextLevel.value}
                </div>
              </>
            ) : (
              <>
                <div className="text-zinc-200">已达最高节点</div>
                <div className="mt-1">继续提升可稳固关系优势</div>
              </>
            )}
          </div>
        </div>

        <p className="mt-3 text-sm leading-relaxed text-zinc-300">
          {currentLevel.description}
        </p>
      </div>

      <div className="rounded-xl border border-white/8 bg-black/20 px-3 py-3 sm:px-4 sm:py-4">
        <div className="text-[10px] tracking-[0.18em] text-zinc-500">
          好感进度
        </div>
        <div className="mt-1 text-[11px] leading-relaxed text-zinc-500">
          0 是战斗分界线，低于 0
          会直接进入对战；其余节点表示进入对应阶段所需的最低好感。
        </div>

        <div className="relative mt-5 pb-12 pt-1 sm:pb-14">
          <div className="absolute left-0 right-0 top-[1.02rem] h-2 rounded-full border border-white/8 bg-gradient-to-b from-white/[0.08] via-white/[0.03] to-black/35 shadow-[inset_0_1px_0_rgba(255,255,255,0.05)]" />
          <div
            className="absolute left-0 top-[1.02rem] h-2 rounded-l-full bg-gradient-to-r from-rose-500/18 via-rose-400/10 to-transparent"
            style={{ width: `${zeroRatio * 100}%` }}
          />
          <div
            className="absolute top-[1.02rem] h-2 rounded-r-full bg-gradient-to-r from-sky-400/10 via-amber-300/10 to-rose-400/16"
            style={{
              left: `${zeroRatio * 100}%`,
              width: `${(1 - zeroRatio) * 100}%`,
            }}
          />
          <div
            className="absolute top-[0.55rem] h-5 w-px bg-white/20"
            style={{ left: `${zeroRatio * 100}%` }}
          />
          <div
            className="absolute top-[1.02rem] h-2 rounded-full shadow-[0_0_16px_rgba(251,191,36,0.16)]"
            style={{
              left: `${fillLeftRatio * 100}%`,
              width: fillWidthPercent,
              background: fillGradient,
            }}
          />

          <div
            className="absolute top-[0.76rem] h-3.5 w-3.5 rounded-full border-2"
            style={{
              left: `${currentRatio * 100}%`,
              transform: getAnchorTransform(currentRatio),
            }}
          >
            <div
              className={`h-full w-full rounded-full border ${currentPointerTone}`}
            />
          </div>

          {AFFINITY_PROGRESS_MARKERS.map((marker) => {
            const markerRatio = getAffinityProgressRatio(marker.value);
            const isReached = isMarkerReached(marker, affinity);
            const isActive = marker.value === activeMarkerValue;

            return (
              <div
                key={`affinity-marker-${marker.value}`}
                className="absolute top-0"
                style={{
                  left: `${markerRatio * 100}%`,
                  transform: getAnchorTransform(markerRatio),
                }}
              >
                <div className="flex w-12 flex-col items-center text-center sm:w-16">
                  <div className="relative flex h-9 items-end justify-center sm:h-10">
                    {isActive ? (
                      <div
                        className={`absolute bottom-0 h-6 w-3 rounded-full blur-[5px] sm:h-7 sm:w-3.5 ${
                          marker.value < 0 ? 'bg-rose-300/20' : 'bg-sky-300/18'
                        }`}
                      />
                    ) : null}
                    <div
                      className={`relative rounded-full border transition-all duration-300 ${
                        isActive
                          ? marker.value < 0
                            ? 'h-7 w-2 border-rose-100/75 bg-gradient-to-b from-rose-100 via-rose-300 to-rose-500 shadow-[0_0_14px_rgba(251,113,133,0.28)] sm:h-8'
                            : 'h-7 w-2 border-sky-50/75 bg-gradient-to-b from-white via-sky-100 to-cyan-300 shadow-[0_0_18px_rgba(125,211,252,0.35)] sm:h-8'
                          : isReached
                            ? marker.value < 0
                              ? 'h-5 w-1.5 border-rose-100/45 bg-gradient-to-b from-rose-200 via-rose-300 to-rose-500 shadow-[0_0_10px_rgba(251,113,133,0.22)] sm:h-6'
                              : 'h-5 w-1.5 border-amber-50/50 bg-gradient-to-b from-amber-100 via-amber-200 to-amber-400 shadow-[0_0_12px_rgba(251,191,36,0.18)] sm:h-6'
                            : 'h-4 w-1.5 border-white/12 bg-gradient-to-b from-zinc-500/60 to-zinc-900/90 sm:h-5'
                      }`}
                    >
                      <div className="absolute inset-x-0 top-0 h-1/3 bg-white/20" />
                    </div>
                  </div>

                  <div
                    className={`text-[9px] font-semibold leading-tight tracking-[0.08em] sm:text-[10px] sm:tracking-[0.14em] ${
                      isActive || isReached ? 'text-zinc-100' : 'text-zinc-500'
                    }`}
                  >
                    {marker.label}
                  </div>
                  <div
                    className={`mt-0.5 text-[9px] leading-none sm:text-[10px] ${
                      isActive || isReached ? 'text-zinc-300' : 'text-zinc-600'
                    }`}
                  >
                    {marker.value}
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}
