"use client"; import { useTranslation } from "react-i18next"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { formatAdminCreditMajorDecimal } from "@/lib/money"; import { cn } from "@/lib/utils"; import type { AgentParentCaps } from "@/types/api/admin-agent"; import { Info } from "lucide-react"; import { AdminNumericStepper } from "@/components/admin/admin-numeric-stepper"; import { AdminStatusBadge } from "@/components/admin/admin-status-badge"; import { AGENT_PERCENT_HARD_MAX, actualShareRateFromRelative, creditLimitRangeIssue, isNumericStepperOutOfRange, maxCreditLimitFromParent, maxDefaultRebatePercent, maxRebatePercentFromParent, } from "@/lib/agent-profile-caps"; export type AgentProfileFieldsProps = { disabled?: boolean; loading?: boolean; parentCaps: AgentParentCaps | null; availableCredit: number | null; canCreateChildAgent: boolean; isSuperAdmin: boolean; shareRate: string; onShareRateChange: (value: string) => void; creditLimit: string; onCreditLimitChange: (value: string) => void; rebateLimit: string; onRebateLimitChange: (value: string) => void; defaultRebate: string; onDefaultRebateChange: (value: string) => void; extraRebate: boolean; onExtraRebateChange: (value: boolean) => void; canCreatePlayer: boolean; onCanCreatePlayerChange: (value: boolean) => void; canCreateChild: boolean; onCanCreateChildChange: (value: boolean) => void; riskTags: string; onRiskTagsChange: (value: string) => void; idPrefix?: string; currencyCode?: string; /** 打开表单时的授信 baseline,用于计算相对上级的上调空间 */ baselineCreditLimit?: number; /** 已下发额度下限(编辑时不可低于 allocated) */ minCreditLimit?: number; /** 一级代理占成/授信/回水仅超管可改(false 时整表只读) */ profileScalarsEditable?: boolean; /** card:用于代理线路详情 Tab 内的卡片表单 */ variant?: "default" | "card"; }; export function AgentProfileFields({ disabled = false, loading = false, parentCaps, availableCredit, canCreateChildAgent, isSuperAdmin, shareRate, onShareRateChange, creditLimit, onCreditLimitChange, rebateLimit, onRebateLimitChange, defaultRebate, onDefaultRebateChange, extraRebate, onExtraRebateChange, canCreatePlayer, onCanCreatePlayerChange, canCreateChild, onCanCreateChildChange, riskTags, onRiskTagsChange, idPrefix = "agent-profile", currencyCode = "NPR", baselineCreditLimit = 0, minCreditLimit = 0, profileScalarsEditable = true, variant = "default", }: AgentProfileFieldsProps): React.ReactElement { const { t } = useTranslation(["agents", "common"]); const fieldDisabled = disabled || loading; const showReadOnlyDisplay = !loading && (!profileScalarsEditable || fieldDisabled); const isCard = variant === "card"; const maxSharePercent = AGENT_PERCENT_HARD_MAX; const maxRebatePercent = maxRebatePercentFromParent(parentCaps); const maxDefaultRebate = maxDefaultRebatePercent(rebateLimit, parentCaps); const maxCreditLimit = maxCreditLimitFromParent(parentCaps, baselineCreditLimit); const actualShare = actualShareRateFromRelative(Number.parseFloat(shareRate) || 0, parentCaps); const creditRangeIssue = creditLimitRangeIssue(creditLimit, { min: minCreditLimit, max: maxCreditLimit, }); return (
{(parentCaps || availableCredit !== null) && !loading ? (
{parentCaps ? (

{t("profile.parentCaps", { defaultValue: "上级占成 {{share}}%,可下发 {{credit}}", share: parentCaps.total_share_rate, credit: formatAdminCreditMajorDecimal(parentCaps.available_credit, currencyCode), })}

) : null} {availableCredit !== null ? (

{t("profile.availableCredit", { defaultValue: "可下发额度 {{amount}}", amount: formatAdminCreditMajorDecimal(availableCredit, currencyCode), })}

) : null}
) : null} {loading ? (

{t("profile.loading", { defaultValue: "正在加载占成与授信…" })}

) : null} {!profileScalarsEditable && !loading ? (

{t("profile.lineRootScalarsReadOnlyHint", { defaultValue: "一级代理的占成、站点授信总额与回水由平台超管配置;如需调整请联系平台管理员。", })}

) : null}
{showReadOnlyDisplay ? ( ) : ( )} {parentCaps ? (

{t("profile.relativeShareCapHint", { defaultValue: "占上级比例最高 100%(上级总占成 {{parent}}%)", parent: parentCaps.total_share_rate, })}

) : (

{t("profile.totalShareCapHint", { defaultValue: "占成比例最高 100%" })}

)} {parentCaps && shareRate && actualShare !== null ? (

{t("profile.actualShareRate", { defaultValue: "实际占成 {{rate}}%", rate: actualShare, })}

) : null}
{showReadOnlyDisplay ? ( ) : ( )} {parentCaps && maxCreditLimit !== undefined && profileScalarsEditable ? (

{t("profile.creditParentCapHint", { defaultValue: "最高 {{max}}(上级可再下发 {{available}})", max: formatAdminCreditMajorDecimal(maxCreditLimit, currencyCode), available: formatAdminCreditMajorDecimal(parentCaps.available_credit, currencyCode), })}

) : null} {profileScalarsEditable && creditRangeIssue === "below_min" ? (

{t("profile.validation.creditBelowAllocated", { defaultValue: "授信额度不能低于已下发给下级/玩家的总额(当前至少 {{min}})", min: formatAdminCreditMajorDecimal(minCreditLimit, currencyCode), })}

) : null} {profileScalarsEditable && creditRangeIssue === "above_max" && maxCreditLimit !== undefined ? (

{t("profile.validation.creditExceedsParentWithMax", { defaultValue: "授信额度不能超过 {{max}}", max: formatAdminCreditMajorDecimal(maxCreditLimit, currencyCode), })}

) : null} {minCreditLimit > 0 ? (

{t("profile.creditAllocatedFloorHint", { defaultValue: "不可低于已下发 {{amount}}", amount: formatAdminCreditMajorDecimal(minCreditLimit, currencyCode), })}

) : null}
{showReadOnlyDisplay ? ( ) : ( )} {parentCaps ? (

{t("profile.rebateParentCapHint", { defaultValue: "不得超过上级回水上限 {{max}}%", max: maxRebatePercent, })}

) : (

{t("profile.rebateHardCapHint", { defaultValue: "回水上限最高 100%" })}

)}
{showReadOnlyDisplay ? ( ) : ( )}

{t("profile.defaultRebateCapHint", { defaultValue: "不得超过本节点回水上限 {{max}}%", max: maxDefaultRebate, })}

{showReadOnlyDisplay ? ( ) : ( onRiskTagsChange(e.target.value)} placeholder={t("profile.riskTagsPlaceholder", { defaultValue: "逗号分隔,如 overdue, high_turnover", })} /> )}
{showReadOnlyDisplay ? ( <> ) : ( <> )}
{!isCard ? (

{t("profile.capabilityHint", { defaultValue: "保存后约束该代理主账号能否开玩家/下级;与平台「代理」角色叠加,以本开关为准。", })}

) : null}
); } function ReadOnlyScalar({ id, value, suffix, className, }: { id?: string; value: string; suffix?: string; className?: string; }): React.ReactElement { return (
{value} {suffix ? {suffix} : null}
); } function ReadOnlySwitchRow({ label, checked, isLast = false, }: { label: string; checked: boolean; isLast?: boolean; }): React.ReactElement { const { t } = useTranslation(["agents", "common"]); return (
{label} {checked ? t("common:status.enabled", { defaultValue: "已开启" }) : t("common:status.disabled", { defaultValue: "已关闭" })}
); } function SwitchRow({ checked, onCheckedChange, label, disabled = false, isLast = false, }: { checked: boolean; onCheckedChange: (value: boolean) => void; label: string; disabled?: boolean; isLast?: boolean; }): React.ReactElement { return (
); }