
import React from 'react';
import { ContentPage } from '../../components/ContentPage';
import { ApiSection } from '../../types';

const utilitiesApi: ApiSection[] = [
  {
    title: 'Chemical.Is',
    description: 'A collection of functions to check the type or state of Chemical objects or other values.',
    entries: [
      { signature: 'Is.Stateful(obj: any): boolean', description: 'Checks if `obj` is a Chemical stateful object (Value, Table, Map, Computed, Reaction).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Value = Chemical.Value\nlocal Is = Chemical.Is\n\nlocal v = Value(1) \nprint(Is.Stateful(v)) -- true` },
      { signature: 'Is.Settable(obj: any): boolean', description: 'Checks if `obj` is a Chemical object that has a `:set()` method (Value, Table, Map).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Value = Chemical.Value\nlocal Is = Chemical.Is\n\nlocal v = Value(1) \nprint(Is.Settable(v)) -- true` },
      { signature: 'Is.Primitive(obj: any): boolean', description: 'Checks if `obj` is a Lua primitive type (string, number, boolean, nil).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Is = Chemical.Is\n\nprint(Is.Primitive(123)) -- true \nprint(Is.Primitive({})) -- false` },
      { signature: 'Is.Literal(obj: any): boolean', description: 'Checks if `obj` is a Lua literal (string, number, boolean, nil - excludes functions, tables, userdata, threads).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Is = Chemical.Is\n\nprint(Is.Literal(true)) -- true \nprint(Is.Literal(function() end)) -- false` },
      { signature: 'Is.Symbol(obj: any, typeOf?: string): boolean', description: 'Checks if `obj` is a Chemical Symbol, optionally checking for a specific symbol type (e.g., "Event", "Change").', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal OnEvent = Chemical.OnEvent\nlocal Is = Chemical.Is\n\nlocal onAct = OnEvent("Activated") \nprint(Is.Symbol(onAct)) -- true \nprint(Is.Symbol(onAct, "Event")) -- true` },
      { signature: 'Is.Array(obj: any): boolean', description: 'Checks if `obj` is a plain Lua table intended to be used as an array (not a Chemical Table/Map).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Is = Chemical.Is\n\nprint(Is.Array({1,2,3})) -- true` },
      { signature: 'Is.StatefulTable(obj: any): boolean', description: 'Checks if `obj` is a Chemical.Table instance.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Table = Chemical.Table\nlocal Is = Chemical.Is\n\nlocal t = Table({}) \nprint(Is.StatefulTable(t)) -- true` },
      { signature: 'Is.StatefulDictionary(obj: any): boolean', description: 'Checks if `obj` is a Chemical.Map instance.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Map = Chemical.Map\nlocal Is = Chemical.Is\n\nlocal m = Map({}) \nprint(Is.StatefulDictionary(m)) -- true` },
      { signature: 'Is.Blueprint(obj: any): boolean', description: 'Checks if `obj` is a Chemical blueprint object (used internally for replication).', example: `-- Internal use mostly` },
      { signature: 'Is.Dead(obj: any): boolean', description: 'Checks if a Chemical object has been destroyed (i.e., its `__destroyed` flag is true).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Value = Chemical.Value\nlocal Is = Chemical.Is\n\nlocal v = Value(1) \nv:destroy() \nprint(Is.Dead(v)) -- true` },
      { signature: 'Is.Destroyed(obj: Instance): boolean', description: 'Checks if a Roblox Instance has been destroyed (its Parent is nil and cannot be reparented).', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Is = Chemical.Is\n\nlocal part = Instance.new("Part") \npart:Destroy() \nprint(Is.Destroyed(part)) -- true` },
    ],
  },
  {
    title: 'Chemical.Peek',
    description: 'Retrieves the current value of a stateful object without establishing a reactive dependency. Useful for inspecting state within functions where you do not want to trigger re-computation or re-execution if that state changes later.',
    entries: [
      {
        signature: 'Chemical.Peek<T>(statefulObject: Stateful<T>): T',
        description: 'Gets the raw value of a Chemical stateful object (Value, Computed, etc.).',
        parameters: [ { name: 'statefulObject', type: 'Stateful<T>', description: 'The Chemical object to peek into.' }],
        returns: { type: 'T', description: 'The raw underlying value.'},
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Computed = Chemical.Computed
local Peek = Chemical.Peek

local count = Value(10)
local doubled = Computed(function()
  -- If we used count:get() here, this Computed would depend on it.
  -- Using Peek avoids that dependency for this specific logic,
  -- though it's unusual to use Peek inside a Computed's main function.
  local currentCount = Peek(count)
  print("Peeking at count:", currentCount) -- This line won't cause re-computation if count changes later just because of this peek.
  return currentCount * 2
end)

local val = Peek(doubled) -- Gets the current computed value without depending on 'doubled'.
print(val) -- 20
        `,
      },
    ],
  },
  {
    title: 'Chemical.Array',
    description: 'Utility functions for working with Lua tables (arrays/dictionaries), often in conjunction with Chemical stateful objects.',
    entries: [
      { signature: 'Array.Transform<K, V, R>(tbl: {[K]: V}, doFn: (k: K, v: V) => R): {[K]: R}', description: 'Recursively transforms values in a table. If a value is a table, it\'s transformed recursively. Otherwise, `doFn` is called.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Array = Chemical.Array\n\nlocal data = { a = 1, b = { c = 2 } } \nlocal transformed = Array.Transform(data, function(k, v) return v * 10 end) \n-- transformed is { a = 10, b = { c = 20 } }` },
      { signature: 'Array.ShallowTransform<K, V, R>(tbl: {[K]: V}, doFn: (k: K, v: V) => R): {[K]: R}', description: 'Shallowly transforms values in a table using `doFn`. Does not recurse.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Array = Chemical.Array\n\nlocal data = { a = 1, b = { c = 2 } } \nlocal transformed = Array.ShallowTransform(data, function(k, v) return typeof(v) == "number" and v * 10 or v end) \n-- transformed is { a = 10, b = { c = 2 } }` },
      { signature: 'Array.Traverse(tbl: {}, doFn: (k: any, v: any) -> ())', description: 'Recursively traverses a table, calling `doFn` for non-table values.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Array = Chemical.Array\n\nlocal data = { a = 1, b = { c = 2 } } \nArray.Traverse(data, function(k, v) print(k, v) end)` },
      { signature: 'Array.Walk(target: {any}, visitor: (path: {any}, value: any) -> ())', description: 'Recursively walks a table, calling `visitor` with the path (array of keys) and value for every node.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Array = Chemical.Array\n\nlocal data = { a = 1, b = { c = 2 } } \nArray.Walk(data, function(path, value) print(table.concat(path, "."), value) end)` },
      { signature: 'Array.FindOnPath<K, V>(tbl: {[K]: V}, path: (string|number)[]): V', description: 'Retrieves a value from a nested table using an array of keys/indices representing the path.', example: `local Chemical = require(game.ReplicatedStorage.Chemical)\nlocal Array = Chemical.Array\n\nlocal data = { user = { profile = { name = "Alice" } } } \nlocal name = Array.FindOnPath(data, {"user", "profile", "name"}) \n-- name is "Alice"` },
    ],
  },
  {
    title: 'Chemical.Alive',
    description: 'Checks if a Chemical object (which has an `.entity` property) is still "alive" in the underlying ECS world (i.e., its entity has not been deleted).',
    entries: [
      {
        signature: 'Chemical.Alive(obj: HasEntity): boolean',
        description: 'Returns true if the Chemical object\'s entity still exists in the ECS world, false otherwise.',
        parameters: [ { name: 'obj', type: 'HasEntity', description: 'A Chemical object with an `.entity` property.' }],
        returns: {type: 'boolean', description: 'True if alive, false otherwise.'},
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Alive = Chemical.Alive

local myValue = Value(10)
print(Alive(myValue)) -- true

myValue:destroy()
print(Alive(myValue)) -- false (or will error if myValue itself is nilled out)
        `,
      },
    ],
  },
  {
    title: 'Chemical.Destroy',
    description: 'A versatile function to destroy various types of objects, including Chemical objects, Roblox Instances, RBXScriptConnections, or even call cleanup functions.',
    entries: [
      {
        signature: 'Chemical.Destroy(subject: any)',
        description: 'Attempts to destroy the given subject. It intelligently handles different types: \n- Chemical objects: Calls their `:destroy()` method. \n- Instances: Calls `:Destroy()`. \n- Connections: Calls `:Disconnect()`. \n- Tables: Clears and nils out metatable, or recursively destroys elements if it\'s an array of destroyables. \n- Functions: Calls the function. \n- Threads: Calls `task.cancel()` on the thread.',
        parameters: [ { name: 'subject', type: 'any', description: 'The item to destroy.' }],
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Destroy = Chemical.Destroy

local val = Value(10)
local part = Instance.new("Part")
local conn = part.Touched:Connect(function() end)
local tbl = { Value(1), Instance.new("Frame") }
local cleanupFn = function() print("cleaned") end

Destroy(val)
Destroy(part)
Destroy(conn)
Destroy(tbl) -- Destroys Value(1) and Frame
Destroy(cleanupFn) -- Prints "cleaned"
        `,
      },
    ],
  },
  {
    title: 'Chemical.Blueprint',
    description: 'Functions related to creating and reading "blueprints" of Chemical state. This is primarily used internally for state replication (e.g., by `Reactor`).',
    entries: [
      {
        signature: 'Blueprint.From(value: any): BlueprintData',
        description: 'Creates a blueprint from a given value or Chemical stateful object. The blueprint describes the structure and initial data, including types of Chemical objects.',
        parameters: [ { name: 'value', type: 'any', description: 'The value or Chemical object to blueprint.'} ],
        returns: { type: 'BlueprintData', description: 'A data structure representing the blueprint.'},
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Map = Chemical.Map
local Blueprint = Chemical.Blueprint
local Tags = Chemical.ECS.Tags -- Assuming ECS is exposed this way for example

local myMap = Map({
  name = Value("Test"),
  count = 10
})
local bp = Blueprint.From(myMap)
-- bp would be a table like:
-- { T = Tags.IsStatefulDictionary, V = {
--     name = { T = Tags.IsStateful, V = "Test" },
--     count = { T = Tags.IsStatic, V = 10 }
--   }
-- }
        `,
        notes: '`BlueprintData` typically looks like `{ T = EntityTag, V = valueOrNestedBlueprints }`.'
      },
      {
        signature: 'Blueprint.Read(blueprintData: BlueprintData): any',
        description: 'Reconstructs a Chemical stateful object or plain Lua value from a blueprint.',
        parameters: [ { name: 'blueprintData', type: 'BlueprintData', description: 'The blueprint data to read.'} ],
        returns: { type: 'any', description: 'The reconstructed Chemical object or value.'},
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Blueprint = Chemical.Blueprint
-- (Assuming 'bp' from the Blueprint.From example and relevant Tags are accessible)

local reconstructedMap = Blueprint.Read(bp)
-- reconstructedMap would be a new Chemical.Map equivalent to myMap
print(reconstructedMap:get().name:get()) -- Output: Test
        `,
      },
    ],
  },
];

export const UtilitiesPage: React.FC = () => {
  return <ContentPage title="Utility Functions" sections={utilitiesApi} />;
};
