import {
    Activity,
    Attribute,
    MetricsSchema,
    type Metrics,
} from "@blade-and-brawn/domain";
import { Type as t, type Static } from "@sinclair/typebox";

// ================
// CALCULATOR
// ================

export type LevelCalculatorOutput = {
    player: number;
    attributes: Record<Attribute, number>;
};

export type NumberMetric = Extract<keyof Metrics, "age" | "weight">;

export const LevelsSchema = t.Record(t.String(), t.Number());
export type Levels = Static<typeof LevelsSchema>;

// ================
// STANDARDS
// ================

export const StandardSchema = t.Object({
    metrics: MetricsSchema,
    levels: LevelsSchema,
});
export type Standard = Static<typeof StandardSchema>;

export const GeneratorSchema = t.Object({
    metric: t.Union([t.Literal("age"), t.Literal("weight")]),
});
export type Generator = Static<typeof GeneratorSchema>;

export const StandardsDataSchema = t.Record(
    t.Enum(Activity),
    t.Object({
        metadata: t.Object({
            attribute: t.Enum(Attribute),
            generators: t.Array(GeneratorSchema),
            unit: t.Union([t.Literal("ms"), t.Literal("cm"), t.Literal("kg")]),
            name: t.String(),
            source: t.String()
        }),
        standards: t.Array(StandardSchema),
    }),
);
export type StandardsData = Static<typeof StandardsDataSchema>;

export const StandardsParamsSchema = t.Object({
    global: t.Object({
        maxLevel: t.Number(),
    }),
    activity: t.Record(t.Enum(Activity), t.Object({
        weightModifier: t.Number(),
        weightSkew: t.Number(),
        ageModifier: t.Number(),
        enableGeneration: t.Boolean(),
        difficultyModifier: t.Number(),
        peakAge: t.Number(),
        stretch: t.Object({
            upper: t.Number(),
            lower: t.Number(),
        }),
    }))
});
export type StandardsParams = Static<typeof StandardsParamsSchema>;

export const StandardsConfigSchema = t.Object({
    data: StandardsDataSchema,
    params: StandardsParamsSchema
});
export type StandardsConfig = Static<typeof StandardsConfigSchema>;
