<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Niwa_AI_Agent_Memory_Manager {
    private $embedding_client;
    private $autonomy_workspace = null;
    private $semantic_index = null;

    public function __construct( $embedding_client = null ) {
        $this->embedding_client = $embedding_client;
        $this->semantic_index   = new Niwa_AI_Agent_Memory_Index( $embedding_client );
    }

    public function set_admin_autonomy_workspace( $workspace ) {
        $this->autonomy_workspace = $workspace;
        if ( $this->semantic_index && method_exists( $this->semantic_index, 'set_workspace' ) ) {
            $this->semantic_index->set_workspace( $workspace );
        }
    }

    public function search_entries( $query, $session_id = '', $limit = 5, $conversation_store = null ) {
        unset( $conversation_store );

        $query      = trim( (string) $query );
        $session_id = trim( (string) $session_id );
        $limit      = max( 1, min( 12, intval( $limit ) ) );
        if ( '' === $query || ! $this->semantic_index ) {
            return array();
        }

        $documents = $this->build_index_documents( $session_id );
        if ( empty( $documents ) ) {
            return array();
        }

        return $this->semantic_index->search(
            $query,
            $documents,
            array(
                'limit'      => $limit,
                'session_id' => $session_id,
            )
        );
    }

    public function search( $query, $session_id = '', $limit = 5, $conversation_store = null ) {
        $results = $this->search_entries( $query, $session_id, $limit, $conversation_store );
        if ( empty( $results ) ) {
            return array();
        }

        $formatted = array();
        foreach ( $results as $result ) {
            if ( ! is_array( $result ) ) {
                continue;
            }

            $path       = isset( $result['path'] ) ? (string) $result['path'] : '';
            $start_line = max( 1, intval( isset( $result['start_line'] ) ? $result['start_line'] : 1 ) );
            $end_line   = max( $start_line, intval( isset( $result['end_line'] ) ? $result['end_line'] : $start_line ) );
            $citation   = $path;
            if ( '' !== $path ) {
                $citation .= $start_line === $end_line ? '#L' . $start_line : '#L' . $start_line . '-L' . $end_line;
            }

            $text = trim( (string) ( isset( $result['snippet'] ) ? $result['snippet'] : '' ) );
            if ( '' !== $citation ) {
                $text .= "\n\nSource: " . $citation;
            }

            $formatted[] = array(
                'text'        => $text,
                'score'       => isset( $result['score'] ) ? round( floatval( $result['score'] ), 3 ) : 0.0,
                'source'      => $path,
                'source_type' => isset( $result['source_type'] ) ? (string) $result['source_type'] : '',
                'session_id'  => isset( $result['session_id'] ) ? (string) $result['session_id'] : '',
                'path'        => $path,
                'start_line'  => $start_line,
                'end_line'    => $end_line,
            );
        }

        return $formatted;
    }

    public function read_entry( $path, $from = 1, $lines = 20 ) {
        if ( ! $this->semantic_index ) {
            return array(
                'path'  => (string) $path,
                'text'  => '',
                'error' => 'Agent memory index nije ucitan.',
            );
        }

        return $this->semantic_index->read_entry( $path, $from, $lines );
    }

    private function build_index_documents( $current_session_id = '' ) {
        if ( $this->autonomy_workspace && method_exists( $this->autonomy_workspace, 'repair_memory_text_artifacts' ) ) {
            $this->autonomy_workspace->repair_memory_text_artifacts();
        }

        $documents = array();

        $documents = array_merge(
            $documents,
            $this->build_bootstrap_documents(),
            $this->build_companion_memory_documents(),
            $this->build_daily_memory_documents(),
            $this->build_session_export_documents( $current_session_id )
        );

        return array_values(
            array_filter(
                $documents,
                function ( $document ) {
                    return is_array( $document ) && ! empty( $document['path'] ) && ! empty( $document['content'] );
                }
            )
        );
    }

    private function build_bootstrap_documents() {
        if ( ! $this->autonomy_workspace ) {
            return array();
        }

        $documents = array();
        if ( method_exists( $this->autonomy_workspace, 'get_operational_memory_file_path' ) ) {
            foreach ( array( 'rules.md', 'learnings.md' ) as $filename ) {
                $path = (string) $this->autonomy_workspace->get_operational_memory_file_path( $filename );
                if ( '' === $path || ! file_exists( $path ) || ! is_readable( $path ) ) {
                    continue;
                }

                $read = Niwa_AI_Text_Normalizer::normalize_file_contents( $path );
                $content = ! empty( $read['success'] ) ? trim( (string) $read['content'] ) : '';
                if ( '' === $content ) {
                    continue;
                }

                $documents[] = array(
                    'path'        => 'memory/operational/' . $filename,
                    'abs_path'    => $path,
                    'content'     => $content,
                    'source_type' => 'operational_memory',
                    'session_id'  => '',
                    'timestamp'   => intval( @filemtime( $path ) ),
                );
            }
        }

        return $documents;
    }

    private function build_session_export_documents( $current_session_id = '' ) {
        if (
            ! $this->autonomy_workspace ||
            ! method_exists( $this->autonomy_workspace, 'list_session_manifests' ) ||
            ! method_exists( $this->autonomy_workspace, 'read_session_manifest' ) ||
            ! method_exists( $this->autonomy_workspace, 'read_session_transcript' )
        ) {
            return array();
        }

        $manifests = (array) $this->autonomy_workspace->list_session_manifests( 16 );
        $selected  = array();

        foreach ( $manifests as $manifest ) {
            if ( ! is_array( $manifest ) || empty( $manifest['session_id'] ) ) {
                continue;
            }

            $session_id = trim( (string) $manifest['session_id'] );
            if ( '' === $session_id ) {
                continue;
            }

            $selected[ $session_id ] = $session_id;
        }

        if ( '' !== $current_session_id ) {
            $selected = array( $current_session_id => $current_session_id ) + $selected;
        }

        $documents = array();
        foreach ( array_values( $selected ) as $session_id ) {
            $manifest = (array) $this->autonomy_workspace->read_session_manifest( $session_id );
            if ( empty( $manifest ) ) {
                continue;
            }

            $records   = (array) $this->autonomy_workspace->read_session_transcript( $session_id, 200 );
            $document  = $this->semantic_index && method_exists( $this->semantic_index, 'build_session_export_document' )
                ? $this->semantic_index->build_session_export_document( $session_id, $manifest, $records )
                : array();

            if ( ! empty( $document ) ) {
                $documents[] = $document;
            }
        }

        return $documents;
    }

    private function build_daily_memory_documents() {
        if (
            ! $this->autonomy_workspace ||
            ! method_exists( $this->autonomy_workspace, 'list_memory_documents' )
        ) {
            return array();
        }

        $documents = array();
        foreach ( (array) $this->autonomy_workspace->list_memory_documents( 48 ) as $record ) {
            if ( ! is_array( $record ) || empty( $record['path'] ) || empty( $record['rel_path'] ) ) {
                continue;
            }

            $abs_path = (string) $record['path'];
            if ( ! file_exists( $abs_path ) || ! is_readable( $abs_path ) ) {
                continue;
            }

            $read = Niwa_AI_Text_Normalizer::normalize_file_contents( $abs_path );
            if ( empty( $read['success'] ) || '' === trim( (string) $read['content'] ) ) {
                continue;
            }

            $rel_path = (string) $record['rel_path'];
            if ( ! preg_match( '#^memory/\d{4}-\d{2}-\d{2}\.md$#', $rel_path ) ) {
                continue;
            }

            $documents[] = array(
                'path'        => $rel_path,
                'abs_path'    => $abs_path,
                'content'     => (string) $read['content'],
                'source_type' => 'daily_memory',
                'session_id'  => '',
                'timestamp'   => isset( $record['modified'] ) ? intval( $record['modified'] ) : intval( @filemtime( $abs_path ) ),
            );
        }

        return $documents;
    }

    private function build_companion_memory_documents() {
        if (
            ! $this->autonomy_workspace ||
            ! method_exists( $this->autonomy_workspace, 'list_memory_documents' )
        ) {
            return array();
        }

        $documents = array();
        foreach ( (array) $this->autonomy_workspace->list_memory_documents( 80 ) as $record ) {
            if ( ! is_array( $record ) || empty( $record['path'] ) || empty( $record['rel_path'] ) ) {
                continue;
            }

            $rel_path    = (string) $record['rel_path'];
            $source_type = $this->classify_companion_memory_source( $rel_path );
            if ( '' === $source_type ) {
                continue;
            }

            $abs_path = (string) $record['path'];
            if ( ! file_exists( $abs_path ) || ! is_readable( $abs_path ) ) {
                continue;
            }

            $read = Niwa_AI_Text_Normalizer::normalize_file_contents( $abs_path );
            if ( empty( $read['success'] ) || '' === trim( (string) $read['content'] ) ) {
                continue;
            }

            $documents[] = array(
                'path'        => $rel_path,
                'abs_path'    => $abs_path,
                'content'     => (string) $read['content'],
                'source_type' => $source_type,
                'session_id'  => '',
                'timestamp'   => isset( $record['modified'] ) ? intval( $record['modified'] ) : intval( @filemtime( $abs_path ) ),
            );
        }

        return $documents;
    }

    private function classify_companion_memory_source( $rel_path ) {
        $rel_path = ltrim( str_replace( '\\', '/', (string) $rel_path ), '/' );
        if ( '' === $rel_path ) {
            return '';
        }

        if ( 'memory/companion/profile.md' === $rel_path ) {
            return 'companion_profile';
        }
        if ( 'memory/companion/current-session.md' === $rel_path ) {
            return 'companion_session';
        }
        if ( 'memory/decisions.md' === $rel_path ) {
            return 'companion_decision';
        }
        if ( false !== strpos( $rel_path, 'memory/diary/current/' ) || false !== strpos( $rel_path, 'memory/diary/archived/' ) ) {
            return 'companion_diary';
        }
        if ( false !== strpos( $rel_path, 'memory/companion/' ) ) {
            return 'companion_document';
        }

        return '';
    }
}
