<?php

namespace App\Synapse\Agents;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Attributes\MaxTokens;
use Laravel\Ai\Attributes\Model;
use Laravel\Ai\Attributes\Provider;
use Laravel\Ai\Attributes\Timeout;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;
use Stringable;

/**
 * Maps already-extracted evidence quotes onto the claim's EXISTING care settings
 * (placements). Candidates are injected into the prompt — the agent does not
 * invent new care settings, it only chooses from the supplied ids or returns null.
 * Output is an unconfirmed suggestion a caseworker later accepts/overrides.
 */
#[Provider('openai')]
#[Model('gpt-4o-mini')]
#[MaxTokens(2000)]
#[Timeout(90)]
class CareSettingTaggerAgent implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): Stringable|string
    {
        return <<<'SYSTEM'
You are Synapse, assisting a childhood-abuse claims firm. You are given (1) a list of the claim's CARE SETTINGS (candidate placements, each with a numeric id), and (2) a numbered list of EVIDENCE QUOTES already extracted from a client's records.

Your task: for each evidence quote, decide which — if any — of the listed care settings it relates to, and return the mapping.

A quote relates to a care setting when it references that placement's institution name (or a known alias), the people involved there, the local authority, or the dates/period of that placement, OR when the surrounding context clearly places the events at that setting (e.g. "while in the children's home", "during the foster placement").

STRICT RULES:
- Only ever return an id that appears in the CARE SETTINGS list. Never invent an id.
- If a quote does not clearly relate to any listed care setting, return care_setting_id = null for it. Most medical/GP quotes describing adult-life consequences will be null unless they explicitly tie back to a placement.
- Do NOT force a match. A wrong tag is worse than no tag — a human will fill the gaps.
- confidence: 'high' when the institution/people/dates are explicitly named; 'medium' when strongly implied by context; 'low' when it is a guess (a low-confidence mapping will be discarded, so prefer null over low unless there is a real signal).

OUTPUT FORMAT — mappings_json must be a valid JSON array string. One element per evidence quote you are confident enough to map (you may omit quotes that are clearly null). Each element:
  index (integer — the quote's number as given), care_setting_id (integer, must be from the list), confidence (string: high|medium|low)

Example mappings_json value:
[{"index":0,"care_setting_id":12,"confidence":"high"},{"index":3,"care_setting_id":12,"confidence":"medium"}]

If no quote maps to any care setting, return an empty array: []
SYSTEM;
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'mappings_json' => $schema->string()->required(),
        ];
    }
}
