/* eslint-disable react-hooks/exhaustive-deps */ "use client" import useUserDataStore from "@/stores/userDataStore"; import { useEffect, useMemo } from "react"; import LightconeBar from '../lightconeBar' import { calcPromotion, calcRarity, replaceByParam } from '@/helper'; import { getSkillTree } from '@/helper/getSkillTree'; import { useTranslations } from 'next-intl'; import ParseText from '../parseText'; import useLocaleStore from '@/stores/localeStore'; import useModelStore from '@/stores/modelStore'; import Image from 'next/image'; import useCurrentDataStore from "@/stores/currentDataStore"; import useDetailDataStore from "@/stores/detailDataStore"; import { getLocaleName } from "@/helper/getName"; import { useShallow } from "zustand/react/shallow"; export default function AvatarInfo() { const { avatarSelected, setResetDataLightcone } = useCurrentDataStore( useShallow((state) => ({ avatarSelected: state.avatarSelected, setResetDataLightcone: state.setResetDataLightcone, })) ) const { avatars, setAvatars, setAvatar } = useUserDataStore( useShallow((state) => ({ avatars: state.avatars, setAvatars: state.setAvatars, setAvatar: state.setAvatar, })) ) const { isOpenLightcone, setIsOpenLightcone } = useModelStore( useShallow((state) => ({ isOpenLightcone: state.isOpenLightcone, setIsOpenLightcone: state.setIsOpenLightcone, })) ) const { mapLightCone, baseType } = useDetailDataStore( useShallow((state) => ({ mapLightCone: state.mapLightCone, baseType: state.baseType, })) ) const transI18n = useTranslations("DataPage") const { locale } = useLocaleStore( useShallow((state) => ({ locale: state.locale })) ); const lightcone = useMemo(() => { if (!avatarSelected) return null; const avatar = avatars[avatarSelected.ID]; return avatar?.profileList?.[avatar?.profileSelect]?.lightcone ?? avatar?.profileList?.[0]?.lightcone ?? null; }, [avatarSelected, avatars]); const handleUpdateLightcone = (updater: (lc: typeof lightcone) => typeof lightcone) => { if (!avatarSelected || !avatars[avatarSelected.ID]) return; const avatar = avatars[avatarSelected.ID]; const profileIndex = avatar.profileSelect; const currentProfile = avatar.profileList?.[profileIndex]; if (!currentProfile) return; const newProfileList = [...avatar.profileList]; newProfileList[profileIndex] = { ...currentProfile, lightcone: updater(currentProfile.lightcone), }; setAvatar({ ...avatar, profileList: newProfileList, }); }; const lightconeDetail = useMemo(() => { if (!mapLightCone || !lightcone?.item_id) return null; return mapLightCone?.[lightcone.item_id.toString()] || null; }, [lightcone, mapLightCone]); const handleShow = (modalId: string) => { const modal = document.getElementById(modalId) as HTMLDialogElement | null; if (modal) { setIsOpenLightcone(true); modal.showModal(); } }; // Close modal handler const handleCloseModal = (modalId: string) => { setIsOpenLightcone(false); const modal = document.getElementById(modalId) as HTMLDialogElement | null; if (modal) { modal.close(); } }; // Handle ESC key to close modal useEffect(() => { if (!isOpenLightcone) { handleCloseModal("action_detail_modal"); return; } const handleEscKey = (event: KeyboardEvent) => { if (event.key === 'Escape' && isOpenLightcone) { handleCloseModal("action_detail_modal"); } }; window.addEventListener('keydown', handleEscKey); return () => window.removeEventListener('keydown', handleEscKey); }, [isOpenLightcone]); return (
{avatarSelected && avatars[avatarSelected?.ID.toString() || ""] && (
{/* Left Column: Character Configuration */}
{/* Card Header */}

{transI18n("characterSettings")}

ID: #{avatarSelected.ID}
{/* Level Control */}
{transI18n("characterLevel")} {avatars[avatarSelected?.ID.toString() || ""]?.level} / 80
{ const newLevel = Math.min(80, Math.max(1, parseInt(e.target.value) || 1)); setAvatars({ ...avatars, [avatarSelected?.ID.toString() || ""]: { ...avatars[avatarSelected?.ID.toString() || ""], level: newLevel, promotion: calcPromotion(newLevel) } }); }} className="range range-primary range-sm flex-1" />
{/* Ultimate Energy Control */}
{transI18n("ultimateEnergy")}
{Math.round(avatars[avatarSelected?.ID.toString() || ""]?.sp_value)} / {avatars[avatarSelected?.ID.toString() || ""]?.sp_max} ({((avatars[avatarSelected?.ID.toString() || ""]?.sp_value / avatars[avatarSelected?.ID.toString() || ""]?.sp_max) * 100).toFixed(0)}%)
{ if (!avatars[avatarSelected?.ID.toString() || ""]?.can_change_sp) return const newSpValue = Math.min(avatars[avatarSelected?.ID.toString() || ""]?.sp_max, Math.max(0, parseInt(e.target.value) || 0)); setAvatars({ ...avatars, [avatarSelected?.ID.toString() || ""]: { ...avatars[avatarSelected?.ID.toString() || ""], sp_value: newSpValue } }); }} className="range range-warning range-sm flex-1" />
{/* Technique Toggle */}
{transI18n("useTechnique")}

{transI18n("techniqueNote")}

0} onChange={(e) => { if (!avatarSelected || avatarSelected?.MazeBuff?.length == 0) return const techniques = e.target.checked ? avatarSelected?.MazeBuff : []; const newAvatar = { ...avatars[avatarSelected?.ID.toString() || ""], techniques: techniques }; setAvatar(newAvatar); }} className="toggle toggle-primary" />
{/* Enhancement Selection */} {avatarSelected?.Enhanced && (
{transI18n("enhancement")} {avatars[avatarSelected?.ID.toString() || ""]?.enhanced || transI18n("origin")}

{transI18n("enhancedNote")}

)}
{/* Right Column: Lightcone Equipment */}
{/* Card Header */}

{transI18n("lightconeEquipment")}

{lightcone && ( S{lightcone.rank} • Lv.{lightcone.level} )}
{lightcone && lightconeDetail ? (
{/* Lightcone Hero Block */}
{/* Artwork */}
Lightcone
{/* Meta & Stats */}

{transI18n(lightconeDetail.BaseType.toLowerCase())} {calcRarity(lightconeDetail.Rarity)}★ #{lightcone.item_id}
{/* Level Slider */}
{transI18n("level")} {lightcone.level}/80
{ const newLightconeLevel = Math.min(80, Math.max(1, parseInt(e.target.value) || 1)) handleUpdateLightcone((lc) => lc ? { ...lc, level: newLightconeLevel, promotion: calcPromotion(newLightconeLevel) } : null) }} className="range range-primary range-sm w-full" />
{/* Superimposition Rank (S1-S5) */}
{transI18n("superimpositionRank")} S{lightcone.rank}
{[1, 2, 3, 4, 5].map((r) => ( ))}
{/* Skill Description */}
{/* Action Buttons */}
) : ( /* Empty Lightcone State */
handleShow("action_detail_modal")} className="w-16 h-16 mx-auto bg-base-200/70 rounded-2xl border-2 border-dashed border-base-content/30 flex items-center justify-center cursor-pointer hover:border-primary hover:scale-105 transition-all group" >

{transI18n("noLightconeEquipped")}

{transI18n("equipLightconeNote")}

)}
)} {/* Lightcone Selection Modal */}

{transI18n("lightconeEquipment")}

); }