import { resolveRoleCombatStats } from '../data/attributeCombat';
import { getAttributeSlotValue } from '../data/attributeResolver';
import {
  type BuildDamageBreakdown,
  formatBuildContributionPercent,
  getBuildContributionQualityLabel,
} from '../data/buildDamage';
import { getResourceLabelsForWorld } from '../services/customWorldPresentation';
import type {
  Character,
  RoleAttributeProfile,
  WorldAttributeSchema,
} from '../types';
import {
  buildCharacterSkillRenderId,
  type ContributionRow,
  formatAttributeMetricValue,
  getAttributeBonusPillClassName,
  getAttributeEffectText,
  getContributionVisualStyle,
  getSkillDeliveryLabel,
  getSkillStyleLabel,
} from './CharacterInfoHelpers';

export function StatusRow({
  label,
  current,
  max,
  tone,
}: {
  label: string;
  current: number;
  max: number;
  tone: 'hp' | 'mp';
}) {
  const ratio = Math.max(0, Math.min(1, max > 0 ? current / max : 0));
  const fillClass =
    tone === 'hp'
      ? 'from-emerald-400 via-lime-300 to-emerald-200'
      : 'from-sky-500 via-cyan-300 to-sky-100';

  return (
    <div className="space-y-1">
      <div className="flex items-center justify-between gap-3 text-[10px] uppercase tracking-[0.16em] text-zinc-400">
        <span>{label}</span>
        <span className="text-zinc-200">
          {current} / {max}
        </span>
      </div>
      <div className="h-2 overflow-hidden rounded-full border border-white/10 bg-black/45">
        <div
          className={`h-full bg-gradient-to-r ${fillClass}`}
          style={{ width: `${ratio * 100}%` }}
        />
      </div>
    </div>
  );
}

export function CharacterIdentityBadges({
  roleLabel,
  levelText = null,
  roleTone = 'sky',
  className = '',
}: {
  roleLabel: string;
  levelText?: string | null;
  roleTone?: 'amber' | 'sky' | 'rose' | 'emerald' | 'zinc';
  className?: string;
}) {
  const roleClass =
    roleTone === 'amber'
      ? 'border-amber-300/20 bg-amber-500/10 text-amber-100'
      : roleTone === 'rose'
        ? 'border-rose-300/20 bg-rose-500/10 text-rose-100'
        : roleTone === 'emerald'
          ? 'border-emerald-300/20 bg-emerald-500/10 text-emerald-100'
          : roleTone === 'zinc'
            ? 'border-white/10 bg-black/20 text-zinc-200'
            : 'border-sky-300/20 bg-sky-500/10 text-sky-100';

  return (
    <div className={`flex flex-wrap items-center gap-2 ${className}`.trim()}>
      <span
        className={`rounded-full border px-2.5 py-1 text-[10px] tracking-[0.16em] ${roleClass}`}
      >
        {roleLabel}
      </span>
      {levelText ? (
        <span className="rounded-full border border-white/10 bg-black/20 px-2.5 py-1 text-[10px] tracking-[0.16em] text-zinc-200">
          {levelText}
        </span>
      ) : null}
    </div>
  );
}

export function PlayerLevelProgress({
  level,
  currentLevelXp,
  xpToNextLevel,
  className = '',
}: {
  level: number;
  currentLevelXp: number;
  xpToNextLevel: number;
  className?: string;
}) {
  const safeLevel = Math.max(1, Math.round(level));
  const safeCurrentLevelXp = Math.max(0, Math.round(currentLevelXp));
  const safeXpToNextLevel = Math.max(0, Math.round(xpToNextLevel));
  const ratio =
    safeXpToNextLevel <= 0
      ? 1
      : Math.max(
          0,
          Math.min(1, safeCurrentLevelXp / safeXpToNextLevel),
        );

  return (
    <div className={className}>
      <div className="flex items-center justify-between gap-3 text-[11px]">
        <div className="font-semibold text-amber-50">Lv.{safeLevel}</div>
        <div className="text-zinc-400">
          {safeXpToNextLevel > 0
            ? `${safeCurrentLevelXp}/${safeXpToNextLevel}`
            : 'MAX'}
        </div>
      </div>
      <div className="mt-2 h-1.5 overflow-hidden rounded-full border border-white/10 bg-black/30">
        <div
          className="h-full rounded-full bg-[linear-gradient(90deg,rgba(251,191,36,0.78),rgba(253,224,71,0.96))]"
          style={{
            width: ratio <= 0 ? '0%' : `${Math.max(6, ratio * 100)}%`,
          }}
        />
      </div>
    </div>
  );
}

export function CharacterSkillsList({
  skills,
  onSelectSkill,
  emptyText = '暂无技能信息',
}: {
  skills: Character['skills'];
  onSelectSkill?: ((skillId: string) => void) | null;
  emptyText?: string;
}) {
  if (skills.length === 0) {
    return (
      <div className="rounded-lg border border-white/5 bg-black/20 px-3 py-3 text-sm text-zinc-500">
        {emptyText}
      </div>
    );
  }

  return (
    <div className="grid gap-2 sm:grid-cols-2">
      {skills.map((skill, index) => {
        const skillRenderId = buildCharacterSkillRenderId(skill, index);
        const content = (
          <>
            <div className="flex items-center justify-between gap-2">
              <div className="font-semibold text-white">{skill.name}</div>
              <span className="rounded-full border border-white/10 bg-white/6 px-2 py-0.5 text-[10px] text-zinc-100">
                {getSkillDeliveryLabel(skill)}
              </span>
            </div>
            <div className="mt-2 grid grid-cols-2 gap-2 text-[11px] text-zinc-400">
              <div>伤害：{skill.damage}</div>
              <div>法力：{skill.manaCost}</div>
              <div>冷却：{skill.cooldownTurns}</div>
              <div>距离：{skill.range}</div>
            </div>
            <div className="mt-2 text-[10px] tracking-[0.16em] text-sky-200/85">
              {getSkillStyleLabel(skill)}
            </div>
          </>
        );

        if (onSelectSkill) {
          return (
            <button
              key={skillRenderId}
              type="button"
              onClick={() => onSelectSkill(skillRenderId)}
              className="rounded-xl border border-white/8 bg-black/20 px-3 py-3 text-left text-sm text-zinc-300 transition-colors hover:border-sky-300/25 hover:bg-sky-500/8"
            >
              {content}
            </button>
          );
        }

        return (
          <div
            key={skillRenderId}
            className="rounded-lg border border-white/5 bg-black/20 px-3 py-3 text-sm text-zinc-300"
          >
            {content}
          </div>
        );
      })}
    </div>
  );
}

export function MultiplierContributionList({
  breakdown,
  onSelectContribution,
}: {
  breakdown: BuildDamageBreakdown;
  onSelectContribution: (row: ContributionRow) => void;
}) {
  const sortedRows = [...breakdown.rows].sort(
    (left, right) =>
      right.bonusDelta - left.bonusDelta ||
      left.label.localeCompare(right.label, 'zh-CN'),
  );

  return (
    <div className="space-y-3 rounded-xl border border-sky-400/12 bg-sky-500/6 px-3 py-3">
      <div className="flex flex-col items-start gap-1 text-[10px] uppercase tracking-[0.16em] text-sky-100/80 sm:flex-row sm:items-center sm:justify-between sm:gap-3">
        <span>状态标签</span>
        <span className="text-[9px] leading-4 text-zinc-400 sm:text-[10px]">
          点击标签查看具体属性加成
        </span>
      </div>
      {sortedRows.length > 0 ? (
        <div className="flex flex-wrap gap-2">
          {sortedRows.map((row) => (
            <button
              key={`formula-tag-${row.label}`}
              type="button"
              onClick={() => onSelectContribution(row)}
              className="min-w-[5.2rem] rounded-xl border px-2.5 py-2 text-left text-[10px] text-white transition-transform hover:-translate-y-0.5 sm:min-w-[6.25rem] sm:px-3"
              style={getContributionVisualStyle(row.bonusDelta)}
              title={`查看 ${row.label} 的标签效果`}
            >
              <div className="flex items-center justify-between gap-2">
                <span className="font-medium">{row.label}</span>
                <span className="text-[11px] font-semibold tracking-[0.12em] text-current/80">
                  {getBuildContributionQualityLabel(row.bonusDelta)}
                </span>
              </div>
              <div className="mt-1 text-[10px] leading-4 text-current/70">
                总加成 {formatBuildContributionPercent(row.bonusDelta)}
              </div>
            </button>
          ))}
        </div>
      ) : (
        <span className="rounded-full border border-white/10 bg-black/20 px-2 py-1 text-[10px] text-zinc-300">
          当前还没有形成有效标签
        </span>
      )}
    </div>
  );
}

export function CharacterAttributeGrid({
  attributeProfile,
  attributeSchema,
  buildBreakdown = null,
  resourceLabels,
  emptyText = '暂无属性信息',
  gridClassName = 'grid grid-cols-1 gap-2 text-sm text-zinc-300 sm:grid-cols-2',
  cardClassName = 'rounded-xl border border-white/8 bg-black/25 px-3 py-2',
}: {
  attributeProfile: RoleAttributeProfile | null | undefined;
  attributeSchema: WorldAttributeSchema;
  buildBreakdown?: BuildDamageBreakdown | null;
  resourceLabels: ReturnType<typeof getResourceLabelsForWorld>;
  emptyText?: string;
  gridClassName?: string;
  cardClassName?: string;
}) {
  const attributeRows = attributeSchema.slots.map((slot) => ({
    slot,
    value: getAttributeSlotValue(attributeProfile, slot.slotId),
  }));
  const attributeBonusBySlot = Object.fromEntries(
    attributeSchema.slots.map((slot) => [
      slot.slotId,
      Number(
        (
          buildBreakdown?.rows.reduce(
            (sum, row) =>
              sum + (row.attributeModifierDeltas?.[slot.slotId] ?? 0),
            0,
          ) ?? 0
        ).toFixed(4),
      ),
    ]),
  ) as Record<string, number>;
  const boostedAttributeProfile = attributeProfile
    ? {
        ...attributeProfile,
        values: {
          ...(attributeProfile.values ?? {}),
          ...Object.fromEntries(
            attributeSchema.slots.map((slot) => {
              const baseValue = attributeProfile.values?.[slot.slotId] ?? 0;
              const totalBonus = attributeBonusBySlot[slot.slotId] ?? 0;

              return [
                slot.slotId,
                Number((baseValue * (1 + totalBonus)).toFixed(4)),
              ];
            }),
          ),
        },
      }
    : null;
  const boostedCombatStats = boostedAttributeProfile
    ? resolveRoleCombatStats(boostedAttributeProfile)
    : null;
  const displayRows = attributeRows.map(({ slot, value }) => {
    const totalBonus = attributeBonusBySlot[slot.slotId] ?? 0;
    const boostedValue = Number((value * (1 + totalBonus)).toFixed(4));

    return {
      slot,
      baseValue: value,
      boostedValue,
      totalBonus,
      effectText: boostedCombatStats
        ? getAttributeEffectText(
            slot.slotId,
            boostedCombatStats,
            resourceLabels,
          )
        : '',
    };
  });

  if (displayRows.length === 0) {
    return <div className="text-sm text-zinc-500">{emptyText}</div>;
  }

  return (
    <div className={gridClassName}>
      {displayRows.map(
        ({ slot, baseValue, boostedValue, totalBonus, effectText }) => (
          <div key={slot.slotId} className={cardClassName}>
            <div className="text-sm font-semibold text-zinc-100">
              {slot.name}
            </div>
            <div className="mt-1 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between sm:gap-3">
              <div className="min-w-0 flex-1">
                <div className="text-xl font-bold text-white sm:text-2xl">
                  {formatAttributeMetricValue(boostedValue)}
                </div>
              </div>
              <div className="flex flex-col items-start gap-1 text-left sm:shrink-0 sm:items-end sm:text-right">
                <span
                  className={`max-w-full rounded-full border px-2 py-0.5 text-[10px] font-medium leading-4 ${getAttributeBonusPillClassName(totalBonus)}`}
                >
                  标签加成 {formatBuildContributionPercent(totalBonus)}
                </span>
                <div className="text-[10px] text-zinc-500">
                  原始 {formatAttributeMetricValue(baseValue)}
                </div>
              </div>
            </div>
            {effectText ? (
              <div className="mt-2 text-[10px] leading-relaxed text-sky-200/85">
                {effectText}
              </div>
            ) : null}
          </div>
        ),
      )}
    </div>
  );
}
