<?php

namespace App\Synapse\Context;

use App\Models\Claim\Claim;

class DsarContext
{
    public static function fromClaim(Claim $claim): string
    {
        $claim->loadMissing([
            'client.previousNames',
            'careSettings.institution.aliases',
            'careSettings.institution.contacts',
            'careSettings.institution.relatedInstitutions',
            'institutions.aliases',
            'institutions.contacts',
            'dsars.institution',
            'communications.recordings.synapseTranscript',
        ]);

        $client = $claim->client;
        $lines  = [];

        // CLIENT INFORMATION
        $lines[] = 'CLIENT INFORMATION';
        $lines[] = 'Full name: ' . ($client?->fullName ?? 'Unknown');

        if ($client?->date_of_birth) {
            $lines[] = 'Date of birth: ' . $client->date_of_birth->format('d M Y');
        }

        if ($client?->previousNames?->isNotEmpty()) {
            $lines[] = 'Previous names: ' . $client->previousNames->pluck('name')->join(', ');
        }

        if ($claim->case_number ?? null) {
            $lines[] = 'Case number: ' . $claim->case_number;
        }

        // CARE SETTINGS
        $lines[] = '';
        $lines[] = 'CARE SETTINGS';

        $careSettings = $claim->careSettings->filter(fn ($cs) => $cs->institution !== null);

        if ($careSettings->isEmpty()) {
            $lines[] = 'No care settings recorded.';
        } else {
            $n = 1;
            foreach ($careSettings as $cs) {
                $inst    = $cs->institution;
                $aliases = $inst->aliases->pluck('alias')->filter()->join(', ');

                $lines[] = '';
                $lines[] = 'CARE SETTING ' . $n++;
                $nameStr = 'Name (as recorded): ' . $inst->display_name;
                if ($aliases) {
                    $nameStr .= ' (also known as: ' . $aliases . ')';
                }
                $lines[] = $nameStr;
                $lines[] = 'Approx Dates: ' . ($cs->dates ?: 'Not recorded');
                $lines[] = 'People Involved: ' . ($cs->people_involved ?: 'Not recorded');
                $lines[] = 'Statement / Notes: ' . ($cs->statement ?: 'None');

                $contacts = $inst->contacts->take(3);
                if ($contacts->isNotEmpty()) {
                    $lines[] = 'Contacts:';
                    foreach ($contacts as $contact) {
                        $contactLine = '  ' . $contact->name;
                        if ($contact->job_title) {
                            $contactLine .= ' (' . $contact->job_title . ')';
                        }
                        $parts = array_filter([(string) $contact->email, (string) $contact->telephone]);
                        if ($parts) {
                            $contactLine .= ' — ' . implode(' / ', $parts);
                        }
                        $lines[] = $contactLine;
                    }
                }

                $related = $inst->relatedInstitutions->take(3);
                if ($related->isNotEmpty()) {
                    $lines[] = 'Related Institutions:';
                    foreach ($related as $rel) {
                        $lines[] = '  ' . $rel->display_name;
                    }
                }
            }
        }

        // CLAIM-LEVEL INSTITUTIONS
        if ($claim->institutions->isNotEmpty()) {
            $lines[] = '';
            $lines[] = 'CLAIM-LEVEL INSTITUTIONS (directly linked)';
            foreach ($claim->institutions as $inst) {
                $aliases = $inst->aliases->pluck('alias')->filter()->join(', ');
                $line    = 'Institution: ' . $inst->display_name;
                if ($aliases) {
                    $line .= ' (also known as: ' . $aliases . ')';
                }
                $pivot = $inst->pivot;
                if ($pivot?->dates ?? null) {
                    $line .= ' | Dates: ' . $pivot->dates;
                }
                $lines[] = $line;

                foreach ($inst->contacts->take(3) as $contact) {
                    $contactLine = '  Contact: ' . $contact->name;
                    $parts = array_filter([(string) $contact->email, (string) $contact->telephone]);
                    if ($parts) {
                        $contactLine .= ' — ' . implode(' / ', $parts);
                    }
                    $lines[] = $contactLine;
                }
            }
        }

        // EXISTING DSARS
        $lines[] = '';
        $lines[] = 'EXISTING DSARS';

        if ($claim->dsars->isEmpty()) {
            $lines[] = 'None sent yet.';
        } else {
            foreach ($claim->dsars as $dsar) {
                $instName = $dsar->institution?->display_name ?? 'Unknown institution';
                $line     = $instName . ' — status: ' . $dsar->status;
                if ($dsar->created_at) {
                    $line .= ' — sent: ' . $dsar->created_at->format('d M Y');
                }
                if ($dsar->received_at) {
                    $line .= ' — received: ' . $dsar->received_at->format('d M Y');
                }
                $lines[] = $line;
            }
        }

        // CALL TRANSCRIPTS (auto-pulled)
        $lines[] = '';
        $lines[] = 'CALL TRANSCRIPTS';

        $transcriptCount = 0;
        foreach ($claim->communications as $communication) {
            foreach ($communication->recordings as $recording) {
                $transcript = $recording->synapseTranscript;
                if (!$transcript) {
                    continue;
                }

                $transcriptCount++;
                $date = $recording->created_at?->format('d M Y') ?? 'Unknown date';
                $lines[] = '';
                $lines[] = 'CALL TRANSCRIPT ' . $transcriptCount . ' — ' . $date;

                if (!empty($transcript->ai_summary)) {
                    $lines[] = 'AI Summary: ' . $transcript->ai_summary;
                } elseif (!empty($transcript->formatted_transcript)) {
                    $lines[] = mb_substr($transcript->formatted_transcript, 0, 3000);
                }

                $lines[] = '---';
            }
        }

        if ($transcriptCount === 0) {
            $lines[] = 'No call transcripts available.';
        }

        return implode("\n", $lines);
    }
}
