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

const reactionApi: ApiSection[] = [
  {
    title: 'Chemical.Reaction',
    description: 'A Reaction is a stateful container, specifically designed for network replication when created by a `Reactor`. It holds reactive state (Values, Tables, Maps, or even nested Reactions) that can be synchronized between server and client. Properties of the container defined in the Reactor constructor are directly accessible on the Reaction instance itself due to proxying.',
    entries: [
      {
        signature: 'Reaction<T>(name: string, key: string, container: T): Reaction<T>',
        description: 'Constructs a new Reaction. Typically, Reactions are created via `Chemical.Reactor:create()` on the server and `Chemical.Reactor:await()` on the client, not directly using this constructor by the end-user for networked state.',
        parameters: [
          { name: 'name', type: 'string', description: 'The name of the Reactor this Reaction belongs to.' },
          { name: 'key', type: 'string', description: 'A unique key identifying this Reaction instance within its Reactor.' },
          { name: 'container', type: 'T', description: 'The initial data structure (often a table containing Chemical Values, Tables, etc.) for the Reaction.' },
        ],
        returns: { type: 'Reaction<T>', description: 'A new Reaction object.' },
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Map = Chemical.Map
local Reaction = Chemical.Reaction -- For conceptual understanding

-- This is how a Reactor might internally create a Reaction.
-- User code typically uses Reactor:create() or Reactor:await().

-- Hypothetical internal creation:
local myPlayerData = Reaction("PlayerData", "player123", {
  health = Value(100),
  position = Map({ x = 0, y = 0, z = 0 })
})

-- Direct access (due to proxying):
myPlayerData.health:set(90)
print(myPlayerData.position:get().x) -- Accessing nested Map's value
        `,
        notes: "End-users primarily interact with Reactions through the `Reactor` API for creation and synchronization. Properties of the Reaction's container are directly accessible on the Reaction instance."
      },
    ],
  },
  {
    title: 'Reaction Properties (Conceptual)',
    description: 'Reactions, when created by a Reactor, have these conceptual properties managed by the system for networking.',
    entries: [
         {
            signature: 'reaction.Name: string',
            description: 'The name of the Reactor that this Reaction instance belongs to.',
            example: ` -- (Conceptual access)
-- local myReaction = PlayerDataReactor:create("player1")
-- print(myReaction.Name) -- "PlayerData"
            `
         },
         {
            signature: 'reaction.Key: string',
            description: 'The unique key identifying this Reaction instance.',
            example: ` -- (Conceptual access)
-- local myReaction = PlayerDataReactor:create("player1")
-- print(myReaction.Key) -- "player1"
            `
         },
         {
            signature: 'reaction.To: {Player} | Symbol',
            description: 'Specifies which players this Reaction is replicated to. Set by the Reactor configuration.',
            example: ` -- (Conceptual access, set during Reactor config)
-- reaction.To might be Chemical.Symbols.All("Players") or an array of Player objects.
            `
         }
    ]
  },
  {
    title: 'Reaction Methods',
    description: 'Properties of the Reaction\'s container are directly accessible. Reaction instances also provide the following methods:',
    entries: [
      {
        signature: 'reaction:get(): T',
        description: 'Retrieves the raw, underlying Lua table/container object that was returned by the Reactor\'s constructor. This is useful if you need the plain data structure itself, without Chemical\'s proxying or methods. If called within a Computed or Effect, it establishes a dependency on the entire Reaction container.',
        returns: { type: 'T', description: 'The raw internal container of the Reaction.' },
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
-- Assuming 'playerDataReaction' is a Reaction created by a Reactor,
-- and its constructor returned a table like:
-- { stats = Chemical.Map({ strength = Value(10) }) }

-- Direct access to proxied properties:
playerDataReaction.stats:get().strength:set(12) -- Works directly on the Chemical.Value
print(playerDataReaction.stats:get().strength:get()) -- Output: 12

-- Using :get() to retrieve the raw container:
local rawPlayerDataContainer = playerDataReaction:get()
-- rawPlayerDataContainer is the actual table: { stats = <Chemical.Map object> }
local rawStatsMap = rawPlayerDataContainer.stats -- This is the Chemical.Map object
local rawStrengthValue = rawStatsMap:get().strength -- This is the Chemical.Value object
print(rawStrengthValue:get()) -- Output: 12
        `,
      },
      {
        signature: 'reaction:destroy()',
        description: 'Destroys the Reaction object. On the server, this also triggers a destroy message to clients. Cleans up all nested Chemical objects within its scope.',
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
-- Assuming 'playerDataReaction' is an existing Reaction

-- Server-side
playerDataReaction:destroy() -- Notifies clients, cleans up server resources.

-- Client-side
-- The Reaction will be destroyed automatically when server sends the message.
        `,
      },
      {
        signature: 'reaction:serialize(): any',
        description: 'Returns a version of the Reaction\'s state suitable for serialization (e.g., for saving to a DataStore). It typically includes only primitive values from nested stateful objects.',
        returns: { type: 'any', description: 'A serializable representation of the Reaction\'s data.' },
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Table = Chemical.Table
local Reaction = Chemical.Reaction -- For example context

local reaction = Reaction("MyData", "item1", {
  name = Value("Test Item"),
  count = Value(5),
  tags = Table({"tag1", "tag2"})
})
local serializedData = reaction:serialize()
-- serializedData might be: { name = "Test Item", count = 5, tags = {"tag1", "tag2"} }
        `,
      },
      {
        signature: 'reaction:snapshot(): any',
        description: 'Returns a deep copy of the current state of the Reaction, with nested stateful objects represented by their current values.',
        returns: { type: 'any', description: 'A snapshot of the Reaction\'s data.' },
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value -- Assuming Value is used inside Reaction
-- Assuming 'myReaction' exists with a structure like { name = Value("Snap") }

local snap = myReaction:snapshot()
-- snap would be { name = "Snap" } (the raw value)
        `,
      },
      {
        signature: 'reaction:blueprint(): Blueprint | { Blueprint }',
        description: 'Generates a blueprint of the Reaction\'s structure and initial values. This is used internally for replication to describe how to reconstruct the Reaction on the client.',
        returns: { type: 'Blueprint | { Blueprint }', description: 'A blueprint object or table of blueprints.' },
        example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
-- Assuming 'myReaction' exists

-- Used internally by the Reactor system.
local bp = myReaction:blueprint()
-- 'bp' would contain type information (T) and values (V) for reconstruction.
        `,
        notes: "This is primarily for internal use by the Chemical library."
      },
    ],
  },
];

export const ReactionPage: React.FC = () => {
  return <ContentPage title="Chemical.Reaction" sections={reactionApi} />;
};
