// D3 재화/보상/레벨/응원/지위아이템 도메인 타입
// Backend Application/Features/Api/{Rewards/GetToday, Member/GetLevel, Member/Items/*, Forum/PostCheer/*}/Response.cs 대응.
// ⚠️ Web.Api Program.cs 에 JsonStringEnumConverter 미등록 → enum 은 전부 숫자로 직렬화됨
//    (ItemKind·EquipSlot 은 정수 코드로 옴 — types/community.ts 와 동일 convention).
//    라벨 맵은 이 파일 하단에 한 곳으로 모은다 (지시 6번 — ItemKind/EquipSlot 라벨 단일 소스).

// ── 재화 (WalletBalanceType) — UI 이원화: 캐시 / 토큰 (d0 §2.2, Frontend/CLAUDE.md 용어 규칙) ──
// 캐시 = PgCharged + Deposit + Adjusted (충전 재화, 상점 구매 전용)
// 토큰 = Reward + Airdrop (활동 적립 재화, 응원·모의투자 전용)
export const CASH_BALANCE_TYPES = ['PgCharged', 'Deposit', 'Adjusted'] as const;
export const TOKEN_BALANCE_TYPES = ['Reward', 'Airdrop'] as const;

// GET /api/wallet → { balances: [{ type, amount }] }
export interface WalletBalanceRow {
	type: string;
	amount: number;
}

export interface WalletResponse {
	id: number;
	memberID: number;
	balance: number;
	balances: WalletBalanceRow[];
}

// 캐시/토큰 합산 헬퍼 — balances 배열에서 파티션별 합계
export function sumCash(balances: WalletBalanceRow[]|undefined|null): number {
	if (!balances) {
		return 0;
	}

	return balances
		.filter(c => (CASH_BALANCE_TYPES as readonly string[]).includes(c.type))
		.reduce((acc, c) => acc + c.amount, 0);
}

export function sumToken(balances: WalletBalanceRow[]|undefined|null): number {
	if (!balances) {
		return 0;
	}

	return balances
		.filter(c => (TOKEN_BALANCE_TYPES as readonly string[]).includes(c.type))
		.reduce((acc, c) => acc + c.amount, 0);
}

// 응원 가용액 = 캐시 + 토큰 (Backend Wallet.GetCheerAvailable 대응 — 캐시→토큰 순 차감)
export function sumCheerAvailable(balances: WalletBalanceRow[]|undefined|null): number {
	return sumCash(balances) + sumToken(balances);
}

// ── GET /api/members/me/level ──
export interface MemberLevelResponse {
	exp: number;
	currentGradeID: number|null;
	currentGradeName: string|null;
	currentGradeImage: string|null;
	currentGradeTextColor: string|null;
	nextGradeID: number|null;
	nextGradeName: string|null;
	nextGradeRequiredExp: number|null;
	expToNextGrade: number|null;
}

// ── GET /api/rewards/me/today ──
// ActionType 은 tinyint 숫자 (Post=1, Comment=2, LikeGiven=3, LikeReceived=4, Attendance=5, CheerReceived=6, Chat=7, PaperReward=8)
export interface RewardActionSummary {
	actionType: number;
	actionName: string;
	count: number;
	expEarned: number;
	pointEarned: number;
	remainingCount: number|null;
	remainingExp: number|null;
	remainingPoint: number|null;
}

export interface RewardsTodayResponse {
	rewardDate: string;
	totalExp: number;
	totalPoint: number;
	actions: RewardActionSummary[];
}

// ── GET /api/posts/{postID}/cheers ──
export interface CheerItem {
	id: number;
	fromMemberID: number;
	fromNickname: string|null;
	amount: number;
	message: string|null;
	createdAt: string;
}

export interface CheerListResponse {
	totalAmount: number;
	count: number;
	recent: CheerItem[];
}

// POST /api/posts/{postID}/cheers → { cheerID }
export interface CheerSendRequest {
	amount: number;
	message?: string|null;
}

export interface CheerSendResponse {
	cheerID: number;
}

// ── ItemKind (Domain Store/ValueObject/ItemKind.cs — 숫자 직렬화) ──
export const ItemKind = {
	Coupon: 1,
	Badge: 2,
	NicknameEffect: 3,
	CommentEffect: 4,
	ChatBanLift: 5,
	PostReset: 6,
	NotePass: 7,
	ExpBooster: 8,
	ProfileImageChange: 9,
	TaglineChange: 10,
	NicknameChange: 11
} as const;
export type ItemKindValue = (typeof ItemKind)[keyof typeof ItemKind];

// ── EquipSlot (Domain Members/ValueObject/EquipSlot.cs — 숫자 직렬화) ──
export const EquipSlot = {
	Badge: 1,
	NicknameEffect: 2,
	CommentEffect: 3
} as const;
export type EquipSlotValue = (typeof EquipSlot)[keyof typeof EquipSlot];

// 장착형(지위) 아이템 종류 — 슬롯을 가지는 것들
export const STATUS_ITEM_KINDS: ItemKindValue[] = [ItemKind.Badge, ItemKind.NicknameEffect, ItemKind.CommentEffect];

// ── GET /api/members/me/items (List/Response.Row) ──
// Kind·EquipSlot 은 숫자. isStatusItem = EquipSlot != null.
export interface MemberItemRow {
	id: number;
	productID: number;
	productName: string;
	thumbnail: string|null;
	kind: ItemKindValue;
	equipSlot: EquipSlotValue|null;
	isEquipped: boolean;
	isStatusItem: boolean;
	effectPayload: string|null;
	durationDays: number;
	acquiredAt: string;
	expiresAt: string|null;
	usedAt: string|null;
	giftFromMemberID: number|null;
	giftFromName: string|null;
}

export interface MemberItemsResponse {
	total: number;
	list: MemberItemRow[];
}

// POST /api/members/me/items/{id}/equip · /unequip → { id, slot, isEquipped }
export interface EquipResponse {
	id: number;
	slot: EquipSlotValue;
	isEquipped: boolean;
}

// ── GET /api/members/equipped-items?ids= (Items/Equipped/Response) ──
export interface EquippedItem {
	slot: EquipSlotValue;
	kind: ItemKindValue;
	productName: string;
	effectPayload: string|null;
	thumbnail: string|null;
}

export interface MemberEquip {
	memberID: number;
	items: EquippedItem[];
}

export interface EquippedItemsResponse {
	members: MemberEquip[];
}

// EffectPayload JSON — 색상·아이콘·애니메이션 키 (Product.EffectPayload 스냅샷)
// 자유 형식이나 렌더에서 안전하게 참조할 필드만 선언 (없으면 무시).
export interface EffectPayload {
	color?: string;
	background?: string;
	textColor?: string;
	icon?: string;
	animation?: string;
	label?: string;
}

export function parseEffectPayload(raw: string|null|undefined): EffectPayload|null {
	if (!raw) {
		return null;
	}

	try {
		const parsed = JSON.parse(raw);
		if (parsed && typeof parsed === 'object') {
			return parsed as EffectPayload;
		}
	} catch {
		// 잘못된 JSON 은 무시 (배지 미표시)
	}

	return null;
}

// ── 라벨 맵 (지시 6번 — ItemKind / EquipSlot 라벨 단일 소스) ──

export const ITEM_KIND_LABEL: Record<ItemKindValue, string> = {
	[ItemKind.Coupon]: '쿠폰',
	[ItemKind.Badge]: '배지',
	[ItemKind.NicknameEffect]: '닉네임 이펙트',
	[ItemKind.CommentEffect]: '댓글 이펙트',
	[ItemKind.ChatBanLift]: '채팅 밴 해제권',
	[ItemKind.PostReset]: '예전 글 초기화권',
	[ItemKind.NotePass]: '쪽지권',
	[ItemKind.ExpBooster]: '경험치 2배 모래시계',
	[ItemKind.ProfileImageChange]: '프로필 이미지 변경권',
	[ItemKind.TaglineChange]: '오늘의 한마디 변경권',
	[ItemKind.NicknameChange]: '닉네임 변경권'
};

export const EQUIP_SLOT_LABEL: Record<EquipSlotValue, string> = {
	[EquipSlot.Badge]: '배지',
	[EquipSlot.NicknameEffect]: '닉네임 이펙트',
	[EquipSlot.CommentEffect]: '댓글 이펙트'
};

export const EQUIP_SLOT_DESC: Record<EquipSlotValue, string> = {
	[EquipSlot.Badge]: '닉네임 옆에 표시되는 배지입니다.',
	[EquipSlot.NicknameEffect]: '닉네임에 색상·강조 효과를 적용합니다.',
	[EquipSlot.CommentEffect]: '내가 쓴 댓글에 배경·강조 효과를 적용합니다.'
};

// 슬롯 노출 순서 (아이템 관리 화면)
export const EQUIP_SLOT_ORDER: EquipSlotValue[] = [EquipSlot.Badge, EquipSlot.NicknameEffect, EquipSlot.CommentEffect];
