import { html, LitElement, nothing, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import {
Flag,
Pack,
Pattern,
Skin,
Subscription,
} from "../../core/CosmeticSchemas";
import { PlayerPattern } from "../../core/Schemas";
import {
PaymentMethod,
ResolvedCosmetic,
translateCosmetic,
} from "../Cosmetics";
import { translateText } from "../Utils";
import "./CapIcon";
import "./CosmeticContainer";
import "./CosmeticInfo";
import { renderPatternPreview } from "./PatternPreview";
import "./PlutoniumIcon";
import { DEFAULT_DOLLAR_LABEL_KEY } from "./PurchaseButton";
@customElement("cosmetic-button")
export class CosmeticButton extends LitElement {
@property({ type: Object })
resolved!: ResolvedCosmetic;
@property({ type: Boolean })
selected: boolean = false;
@property({ type: Function })
onSelect?: (resolved: ResolvedCosmetic) => void;
@property({ type: Function })
onPurchase?: (resolved: ResolvedCosmetic, method: PaymentMethod) => void;
/** True if the user already has a subscription (any tier). */
@property({ type: Boolean })
userHasSubscription: boolean = false;
createRenderRoot() {
return this;
}
private handleClick() {
this.onSelect?.(this.resolved);
}
private get displayName(): string {
const c = this.resolved.cosmetic;
if (c === null) {
return translateText("territory_patterns.pattern.default");
}
if (this.resolved.type === "pattern" || this.resolved.type === "skin") {
return translateCosmetic("territory_patterns.pattern", c.name);
}
if (this.resolved.type === "pack") {
return (c as Pack).displayName;
}
if (this.resolved.type === "subscription") {
return translateCosmetic("subscriptions", c.name);
}
return translateCosmetic("flags", c.name);
}
private renderPreview(): TemplateResult {
if (this.resolved.type === "pattern") {
const c = this.resolved.cosmetic;
const playerPattern: PlayerPattern | null =
c === null
? null
: {
name: c.name,
patternData: (c as Pattern).pattern,
colorPalette: this.resolved.colorPalette ?? undefined,
};
return renderPatternPreview(playerPattern, 150, 150);
}
if (this.resolved.type === "skin") {
const c = this.resolved.cosmetic as Skin | null;
if (c === null) {
// "Default" tile — visually consistent with pattern's default tile.
return html`
${translateText("territory_patterns.pattern.default")}
`;
}
return html`
`;
}
if (this.resolved.type === "pack") {
const pack = this.resolved.cosmetic as Pack;
const isHard = pack.currency === "hard";
const icon = isHard
? html``
: html``;
const colorClass = isHard ? "text-green-400" : "text-amber-700";
const currencyKey = isHard ? "cosmetics.hard" : "cosmetics.soft";
return html`
${icon}
${pack.amount.toLocaleString()}
${translateText(currencyKey)}
${pack.bonusAmount > 0
? html`
${translateText("cosmetics.free", {
numFree: pack.bonusAmount.toLocaleString(),
})}
`
: nothing}
`;
}
if (this.resolved.type === "subscription") {
const sub = this.resolved.cosmetic as Subscription;
return html`
${sub.description}
${sub.dailyHardCurrency.toLocaleString()}
${translateText("cosmetics.per_day")}
${sub.dailySoftCurrency.toLocaleString()}
${translateText("cosmetics.per_day")}
`;
}
const c = this.resolved.cosmetic as Flag;
return html`
{
const img = e.currentTarget as HTMLImageElement;
const fallback = "/flags/xx.svg";
if (img.src && !img.src.endsWith(fallback)) {
img.src = fallback;
}
}}
/>`;
}
render() {
const c = this.resolved.cosmetic;
const priced = c as Pattern | Skin | Flag | Pack | null;
const priceHard = priced?.priceHard;
const priceSoft = priced?.priceSoft;
const artist = priced?.artist;
const isPurchasable = this.resolved.relationship === "purchasable";
const type = this.resolved.type;
const isPattern = type === "pattern";
const isSkin = type === "skin";
const isOwnedSubscription =
type === "subscription" && this.resolved.relationship === "owned";
const dollarLabelKey =
type === "subscription"
? this.userHasSubscription
? "store.switch_button"
: "store.subscribe_button"
: DEFAULT_DOLLAR_LABEL_KEY;
const priceSuffix =
type === "subscription" ? translateText("store.price_per_month") : "";
const sizeClass = type === "flag" ? "gap-1 p-1.5 w-36" : "gap-2 p-3 w-48";
const crazygamesClass = isPattern || isSkin ? "no-crazygames " : "";
return html`
this.onPurchase?.(this.resolved, "dollar")
: undefined}
.onPurchaseHard=${isPurchasable && priceHard !== undefined
? () => this.onPurchase?.(this.resolved, "hard")
: undefined}
.onPurchaseSoft=${isPurchasable && priceSoft !== undefined
? () => this.onPurchase?.(this.resolved, "soft")
: undefined}
.name=${this.displayName}
>
${isOwnedSubscription
? html`
${translateText("store.current_plan")}
`
: nothing}
`;
}
}