<?php

namespace App\Synapse\Agents;

use App\Synapse\Tools\SearchInstitutionsTool;
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\Contracts\HasTools;
use Laravel\Ai\Promptable;
use Stringable;

/**
 * Identifies the source institution a manually-uploaded document came from,
 * matching against the firm's existing Institutions database (never free text).
 * Output is an unconfirmed suggestion a caseworker later accepts/overrides.
 */
#[Provider('openai')]
#[Model('gpt-4o')]
#[MaxTokens(1000)]
#[Timeout(90)]
class DocumentSourceIdentifierAgent implements Agent, HasStructuredOutput, HasTools
{
    use Promptable;

    public function tools(): iterable
    {
        return [
            new SearchInstitutionsTool(),
        ];
    }

    public function instructions(): Stringable|string
    {
        return <<<'SYSTEM'
You are Synapse, assisting a legal claims management firm. You are given a document (its filename, document type, and the text from its first pages — typically a letterhead, sender block, or record header). Your task is to identify which institution in the firm's database this document was SOURCED FROM — i.e. who produced or sent it (an NHS trust, a GP surgery, a local authority / council social-services department, a care provider, the police, a school, etc.).

Steps:
1. Extract the sending organisation from the letterhead, header, logo text, address block, footer, or any "from" / reference lines. Prefer the organisation that authored the record over any organisation merely mentioned within it.
2. Use SearchInstitutionsTool to find that organisation in the database. Try several search terms if needed (full name, shortened form, acronym, the NHS trust name, the council name).
3. Return the matching institution's id.

Confidence ratings:
- high: the letterhead/header clearly names an organisation that maps to a single database institution.
- medium: the source organisation is identifiable and a plausible single institution is found, but the name is approximate.
- low: the source is unclear, or several institutions could match.

If you cannot identify the source institution with at least medium confidence, set institution_id to null. Only return an id that SearchInstitutionsTool actually returned — never invent one.
SYSTEM;
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'institution_id' => $schema
                ->integer()
                ->nullable()
                ->description('The database id of the source institution, or null if not identified')
                ->required(),
            'confidence' => $schema
                ->string()
                ->description('One of: high, medium, low')
                ->required(),
            'reasoning' => $schema
                ->string()
                ->description('Brief explanation of how the source was determined')
                ->required(),
        ];
    }
}
