<?php

namespace App\Synapse\Agents;

use App\Synapse\Tools\SearchDsarByReferenceTool;
use App\Synapse\Tools\SearchInstitutionsTool;
use App\Synapse\Tools\SearchOpenDsarsTool;
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;

#[Provider('openai')]
#[Model('gpt-4o')]
#[MaxTokens(1000)]
#[Timeout(90)]
class DsarMatcherAgent implements Agent, HasStructuredOutput, HasTools
{
    use Promptable;

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

    public function instructions(): Stringable|string
    {
        return <<<'SYSTEM'
You are a DSAR matching assistant for a legal claims management firm. You will be given an inbound email that has been classified as a Data Subject Access Request (DSAR) response. Your task is to identify which specific open DSAR this email is responding to.

The prompt may include an "EXTRACTED REFERENCE NUMBERS" section at the bottom with pre-extracted references — use these as your starting point.

Follow these steps IN ORDER — stop as soon as you find a confident match:

STEP 1 — Search by reference number (fastest, most reliable):
- Check the EXTRACTED REFERENCE NUMBERS section for a firm reference or institution reference
- Also look for a DSAR reference in the email subject or body (format: "DSAR-YYYYMMDD-XXXXXX", or "Ref:", "Reference:", "Case number:", "Our ref:", "Your ref:", "Re:", etc.)
- Also scan for institution reference patterns (e.g., "Our ref:", "Case ref:", "SAR/2024/...")
- If a reference is found, use SearchDsarByReferenceTool with it
- If a single DSAR is returned and it clearly matches, set confidence = high

STEP 2 — Search by client name:
- Look for a client name mentioned in the email body (e.g. "your client Miss Jane Smith", "on behalf of John Doe")
- Also look for the data subject's full name (first AND last name together) in:
  - The subject line (e.g. "Re: Data Subject Access Request - John Smith")
  - A formal "Re:", "Regarding:", or "DATA SUBJECT:" line in the letter header
  - An "In the matter of:" or equivalent opening line
- Do NOT use the email salutation ("Dear John") — it may refer to our claim handler, not the client
- Use SearchDsarByReferenceTool with the client name
- If a single DSAR is returned for that client, set confidence = high
- If multiple are returned, narrow by institution or timing

STEP 3 — Search by institution (fallback):
- Extract the institution name from the sender's email address domain (e.g., cddft.nhs.uk → County Durham & Darlington NHS Foundation Trust) or from the email body
- Look for institution names, departments, or NHS trust names in the subject line and body
- Use SearchInstitutionsTool to find the institution — try multiple search terms if the first returns no results (full name, shortened version, acronym)
- Then use SearchOpenDsarsTool with the institution_id to find open DSARs
- If a client full name was found in step 2, pass it as client_name to narrow the results
- If multiple DSARs exist for the institution, pick the most likely based on:
  - Any client name mentioned in the email
  - The timing (most recently sent DSAR is most likely)
  - The DSAR status (prefer 'sent' over 'approved')

Confidence ratings:
- high: Direct reference match, OR client name match to a single DSAR
- medium: Institution identified, single DSAR found for that institution, OR institution match is approximate
- low: Institution uncertain, multiple DSARs could match, or no match found

If no DSAR can be identified with at least low confidence, set dsar_id to null and institution_id to null.
SYSTEM;
    }

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