/// <cts-enable />
import {
  Cell,
  generateObject,
  handler,
  ifElse,
  lift,
  NAME,
  recipe,
  str,
  toSchema,
  UI,
} from "commontools";

interface InputState {
  number: Cell<number>;
}

interface NumberStory {
  number: number;
  story: string;
  title: string;
  storyOrigin: string;
  seeAlso: number[];
  imagePrompt: string;
}

interface SetNumberEvent {
  number: Cell<number>;
  n: number;
}

// Handler to increment the number
const adder = handler<unknown, InputState>((_, state) => {
  state.number.set(state.number.get() + 1);
});

// Handler to set a specific number
const setNumber = handler((_, state: { number: Cell<number>; n: number }) => {
  state.number.set(state.n);
});

// Generate the prompt for the LLM
const generatePrompt = lift(({ number }: { number: number }) => {
  return {
    prompt:
      `You are the parent of a young child who loves to learn about numbers. Luckily for your child, you are a historian of numbers and when the child says a number you make up an interesting story about it, including the history of the number. The child is currently at ${number}. Also return a recommendation for other numbers that might be interesting to the child to learn about next.`,
    schema: outputSchema,
  };
});

// Generate an image URL from the prompt
const generateImageUrl = lift(({ imagePrompt }: { imagePrompt: string }) => {
  return `/api/ai/img?prompt=${encodeURIComponent(imagePrompt)}`;
});

const inputSchema = toSchema<InputState>({
  default: { number: 0 },
});

const outputSchema = toSchema<NumberStory>();

export default recipe(inputSchema, outputSchema, (cell) => {
  // Use generateObject to get structured data from the LLM
  const { result: object, pending } = generateObject<NumberStory>(
    generatePrompt({ number: cell.number }),
  );

  const imageUrl = generateImageUrl({
    imagePrompt: object?.imagePrompt || "robot thinking",
  });

  return {
    [NAME]: str`Number Story: ${object?.title || "Loading..."}`,
    [UI]: (
      <div>
        <ct-button onClick={adder({ number: cell.number })}>
          Current number: {cell.number} (click to increment)
        </ct-button>
        {ifElse(
          pending,
          <p>Generating story...</p>,
          <div>
            <h1>{object?.title}</h1>
            <p>
              <img
                src={imageUrl}
              />
            </p>
            <p>{object?.story}</p>
            <p>
              <em>{object?.storyOrigin}</em>
            </p>
            <div>
              <p>See also these interesting numbers:</p>
              <ul>
                {object?.seeAlso?.map((n: number) => (
                  <li>
                    <ct-button
                      onClick={setNumber({ number: cell.number, n })}
                    >
                      {n}
                    </ct-button>
                  </li>
                ))}
              </ul>
            </div>
          </div>,
        )}
      </div>
    ),
    number: cell.number,
    ...object,
  };
});
