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

export const IntroductionPage: React.FC = () => {
  const intro = (
    <>
      <p className="mb-4">
        Chemical is a Luau library designed for building applications with a reactive programming paradigm, primarily within environments like Roblox. It provides tools for managing state, creating derived data, handling side effects, and composing user interfaces in a declarative way.
      </p>
      <p className="mb-4">
        Inspired by modern frontend frameworks, Chemical aims to simplify complex state interactions and UI logic by providing a structured and predictable way to handle data flow.
      </p>
    </>
  );

  const sections = [
    {
      title: "Key Features",
      entries: [
        {
          signature: "Reactive Primitives",
          description: "Includes `Value`, `Computed`, and `Effect` for fine-grained reactive control.",
          example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Computed = Chemical.Computed
local Effect = Chemical.Effect

-- Create a reactive value
local count = Value(0)

-- Create a computed value derived from count
local doubled = Computed(function()
  return count:get() * 2
end)

-- Create an effect that runs when count changes
Effect(function()
  print("Count changed to:", count:get())
  print("Doubled is:", doubled:get())
end)

count:set(5) -- This will trigger the effect
-- Output:
-- Count changed to: 5
-- Doubled is: 10
          `,
        },
        {
          signature: "Stateful Collections",
          description: "Manage lists and dictionaries with `Table` and `Map`, which propagate changes reactively.",
          example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Table = Chemical.Table
local Effect = Chemical.Effect

local items = Table({"apple", "banana"})
Effect(function()
  print("Items:", table.concat(items:get(), ", "))
end)

items:insert("cherry")
-- Output:
-- Items: apple, banana
-- (After scheduler runs)
-- Items: apple, banana, cherry
          `,
        },
        {
            signature: "Declarative UI Composition",
            description: "Use the `Compose` API to build and update UI elements based on reactive state.",
            example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Computed = Chemical.Computed
local Compose = Chemical.Compose
local Children = Chemical.Symbols.Children -- Alias for Children key
-- Assuming playerGui is defined: local playerGui = game.Players.LocalPlayer:WaitForChild("PlayerGui")


local name = Value("Player")
local score = Value(100)

local MyScreenGui = Compose("ScreenGui")({
  Parent = playerGui,
  [Children] = { -- Use the aliased Children symbol
    Compose("TextLabel")({
      Name = "PlayerName",
      Position = UDim2.new(0.5, 0, 0.1, 0),
      AnchorPoint = Vector2.new(0.5, 0.5),
      Text = Computed(function()
        return "Name: " .. name:get()
      end),
      TextColor3 = Color3.new(1,1,1),
      BackgroundTransparency = 1,
      Size = UDim2.new(0, 200, 0, 30)
    }),
    Compose("TextLabel")({
      Name = "PlayerScore",
      Position = UDim2.new(0.5, 0, 0.2, 0),
      AnchorPoint = Vector2.new(0.5, 0.5),
      Text = Computed(function()
        return "Score: " .. score:get()
      end),
      TextColor3 = Color3.new(1,1,1),
      BackgroundTransparency = 1,
      Size = UDim2.new(0, 200, 0, 30)
    })
  }
})

-- Later, when state changes, the UI updates automatically
name:set("Hero")
score:set(150)
            `,
        },
        {
          signature: "Networked State with Reactors",
          description: "Synchronize state across server and clients using `Reactor` and `Reaction` objects for multiplayer experiences.",
          example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Reactor = Chemical.Reactor
local Effect = Chemical.Effect

-- Server-side
local PlayerDataReactor = Reactor({ Name = "PlayerData" }, function(key_playerIdString, initialData)
  -- 'key_playerIdString' is the key, typically not stored in this returned table.
  initialData = initialData or {}
  return {
    Health = Value(initialData.Health or 100),
    Mana = Value(initialData.Mana or 50)
  }
end)

local player1DataReaction = PlayerDataReactor:create("player1_id", { Health = 90 })
-- Access properties directly on the reaction:
player1DataReaction.Health:set(80) -- Change will replicate

-- Client-side
local player1DataClient = PlayerDataReactor:await("player1_id")
-- player1DataClient is now the Reaction object
if player1DataClient then
    Effect(function()
        print("Player 1 Health:", player1DataClient.Health:get())
    end)
end
          `,
        },
      ],
    },
    {
        title: "Philosophy",
        entries: [
            {
                signature: "Data Flow",
                description: "Chemical promotes a unidirectional data flow. State changes trigger computations, which in turn can trigger effects (like UI updates or network calls). This makes applications easier to reason about.",
                example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
local Value = Chemical.Value
local Computed = Chemical.Computed
local Effect = Chemical.Effect

-- State (Value) -> Derived State (Computed) -> Side Effect (Effect)
local function UpdateDisplay(text) print("Display: " .. text) end

local price = Value(10)
local quantity = Value(2)

local totalCost = Computed(function()
  return price:get() * quantity:get()
end)

Effect(function()
  UpdateDisplay("Total Cost: $" .. totalCost:get())
end)

price:set(12) -- Triggers totalCost recomputation, then updates display
quantity:set(3) -- Triggers totalCost recomputation, then updates display
                `
            },
            {
                signature: "Modularity",
                description: "The library is structured with clear separation of concerns: core reactivity, state management, UI composition, and networking are distinct but interoperable parts.",
                example: `
local Chemical = require(game.ReplicatedStorage.Chemical)
-- Assuming modules are set up in ReplicatedStorage.Chemical.Modules
-- local PlayerProfileReactor = require(game.ReplicatedStorage.Chemical.Modules.PlayerProfileReactor) -- Uses Reactor
-- local HUD = require(game.ReplicatedStorage.Chemical.Modules.HUDComponent) -- Uses Compose

-- Mock for example purposes
local PlayerProfileReactor = {
  await = function(playerId) 
    print("Mock Reactor: Awaiting profile for", playerId)
    -- Simulate awaiting a profile by returning it directly for example simplicity
    -- In a real scenario, this would yield until the data is available.
    return { 
        UserId = playerId, 
        Name = Chemical.Value("MockPlayer-" .. playerId:sub(1,4)) 
    }
  end
}
local HUD = { Render = function(profile) print("Rendering HUD for", profile.Name:get()) end }
-- End Mock

local player = game.Players.LocalPlayer
local profileReaction = PlayerProfileReactor:await(tostring(player.UserId))
if profileReaction then
    HUD.Render(profileReaction) -- HUD component consumes reactive profile data
end
                `
            }
        ]
    }
  ];

  return <ContentPage title="Introduction to Chemical" introduction={intro} sections={sections} />;
};
