<?php

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

trait Niwa_AI_Tools_Skills {

    private function preview_skill_create( $args ) {
        $name        = isset( $args['name'] ) ? trim( (string) $args['name'] ) : '';
        $description = isset( $args['description'] ) ? trim( (string) $args['description'] ) : '';
        $content     = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';
        $triggers    = isset( $args['triggers'] ) && is_array( $args['triggers'] ) ? $args['triggers'] : array();
        $scope       = isset( $args['scope'] ) ? trim( (string) $args['scope'] ) : 'general';

        if ( '' === $name || '' === $content ) {
            return array( 'success' => false, 'error' => 'Skill mora imati name i content.' );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'        => 'skill_create',
                'args'        => $args,
                'label'       => 'Kreiranje skilla "' . $name . '"',
                'description' => 'Kreirace skill sa opisom: ' . mb_substr( $description, 0, 120 ),
                'risk'        => 'low',
                'triggers'    => $triggers,
                'scope'       => $scope,
            ),
        );
    }

    private function validate_skill_create_action( $args ) {
        $name    = isset( $args['name'] ) ? trim( (string) $args['name'] ) : '';
        $content = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';
        if ( '' === $name ) {
            return array( 'success' => false, 'error' => 'Skill name nedostaje.' );
        }
        if ( '' === $content ) {
            return array( 'success' => false, 'error' => 'Skill content nedostaje.' );
        }
        if ( strlen( $content ) > 262144 ) {
            return array( 'success' => false, 'error' => 'Skill content je prevelik (max 256 KB).' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_create_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'create_skill' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args        = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $name        = isset( $args['name'] ) ? trim( (string) $args['name'] ) : '';
        $description = isset( $args['description'] ) ? trim( (string) $args['description'] ) : '';
        $content     = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';
        $triggers    = isset( $args['triggers'] ) && is_array( $args['triggers'] ) ? $args['triggers'] : array();
        $scope       = isset( $args['scope'] ) ? trim( (string) $args['scope'] ) : 'general';

        $slug = sanitize_file_name( sanitize_title( $name ) );

        $result = $this->skills_manager->create_skill( $slug, $name, $description, $content, array(
            'triggers' => $triggers,
            'scope'    => $scope,
            'source'   => 'self',
        ) );

        if ( ! empty( $result['success'] ) ) {
            $result['rollback'] = array(
                array(
                    'type' => 'skill_delete',
                    'slug' => isset( $result['slug'] ) ? $result['slug'] : $slug,
                ),
            );
        }

        return $result;
    }

    private function preview_skill_delete( $args ) {
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        if ( '' === $slug ) {
            return array( 'success' => false, 'error' => 'Slug za brisanje nije naveden.' );
        }

        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'get_skill' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $skill = $this->skills_manager->get_skill( $slug );
        if ( empty( $skill['success'] ) ) {
            return array( 'success' => false, 'error' => 'Skill "' . $slug . '" ne postoji.' );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'        => 'skill_delete',
                'args'        => $args,
                'label'       => 'Brisanje skilla "' . ( isset( $skill['name'] ) ? $skill['name'] : $slug ) . '"',
                'description' => 'Trajno ce obrisati skill: ' . ( isset( $skill['description'] ) ? $skill['description'] : '' ),
                'risk'        => 'medium',
            ),
        );
    }

    private function validate_skill_delete_action( $args ) {
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        if ( '' === $slug ) {
            return array( 'success' => false, 'error' => 'Slug za brisanje nedostaje.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_delete_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'delete_skill' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';

        return $this->skills_manager->delete_skill( $slug );
    }

    private function preview_skill_import( $args ) {
        $content        = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';
        $archive_base64 = isset( $args['archive_base64'] ) ? trim( (string) $args['archive_base64'] ) : '';
        $filename       = isset( $args['filename'] ) ? trim( (string) $args['filename'] ) : '';

        if ( '' === $content && '' === $archive_base64 ) {
            return array( 'success' => false, 'error' => 'Prazan sadrzaj za import.' );
        }

        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'parse_frontmatter' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        if ( '' !== $archive_base64 ) {
            $name = '' !== $filename ? pathinfo( $filename, PATHINFO_FILENAME ) : 'zip-skill-package';
        } else {
            $parsed = $this->skills_manager->parse_frontmatter( $content );
            $meta   = $parsed['meta'];
            $name   = isset( $meta['name'] ) ? trim( (string) $meta['name'] ) : ( '' !== $filename ? pathinfo( $filename, PATHINFO_FILENAME ) : 'nepoznat' );
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'        => 'skill_import',
                'args'        => $args,
                'label'       => 'Import skilla "' . $name . '"',
                'description' => 'Importovace skill iz poslatog sadrzaja' . ( '' !== $filename ? ' (fajl: ' . $filename . ')' : '' ),
                'risk'        => 'low',
                'detected_name' => $name,
            ),
        );
    }

    private function validate_skill_import_action( $args ) {
        $content        = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';
        $archive_base64 = isset( $args['archive_base64'] ) ? trim( (string) $args['archive_base64'] ) : '';
        if ( '' === $content && '' === $archive_base64 ) {
            return array( 'success' => false, 'error' => 'Prazan sadrzaj za import.' );
        }
        if ( '' !== $content && strlen( $content ) > Niwa_AI_Admin_Autonomy_Skills::MAX_SKILL_SIZE ) {
            return array( 'success' => false, 'error' => 'Sadrzaj je prevelik za import (max 256 KB).' );
        }
        if ( '' !== $archive_base64 ) {
            if ( strlen( $archive_base64 ) > 1398104 ) {
                return array( 'success' => false, 'error' => 'ZIP payload je prevelik za import.' );
            }
            $decoded = base64_decode( $archive_base64, true );
            if ( false === $decoded || '' === $decoded ) {
                return array( 'success' => false, 'error' => 'archive_base64 nije validan base64 payload.' );
            }
        }
        return array( 'success' => true );
    }

    private function execute_skill_import_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'import_skill_from_content' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args           = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $content        = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';
        $archive_base64 = isset( $args['archive_base64'] ) ? trim( (string) $args['archive_base64'] ) : '';
        $filename       = isset( $args['filename'] ) ? trim( (string) $args['filename'] ) : '';

        if ( '' !== $archive_base64 ) {
            if ( ! method_exists( $this->skills_manager, 'import_skill_from_zip' ) ) {
                return array( 'success' => false, 'error' => 'ZIP import nije dostupan u skills manageru.' );
            }
            $decoded = base64_decode( $archive_base64, true );
            if ( false === $decoded || '' === $decoded ) {
                return array( 'success' => false, 'error' => 'archive_base64 nije validan base64 payload.' );
            }
            $tmp = Niwa_AI_Admin_Autonomy_Temp_Files::create( '' !== $filename ? $filename : 'niwa-skill-import.zip' );
            if ( ! $tmp || false === file_put_contents( $tmp, $decoded, LOCK_EX ) ) {
                return array( 'success' => false, 'error' => 'Ne mogu da sacuvam privremeni ZIP za import.' );
            }
            $result = $this->skills_manager->import_skill_from_zip( $tmp );
            @unlink( $tmp );
        } else {
            $result = $this->skills_manager->import_skill_from_content( $content, $filename );
        }

        if ( ! empty( $result['success'] ) && isset( $result['slug'] ) ) {
            $result['rollback'] = array(
                array(
                    'type' => 'skill_delete',
                    'slug' => (string) $result['slug'],
                ),
            );
        }

        return $result;
    }

    private function preview_skill_import_from_github( $args ) {
        $args = is_array( $args ) ? $args : array();
        $runtime_context = is_array( $this->runtime_context ) ? $this->runtime_context : array();
        $workflow        = isset( $runtime_context['extension_workflow'] ) && is_array( $runtime_context['extension_workflow'] ) ? $runtime_context['extension_workflow'] : array();
        $workflow_status = isset( $workflow['status'] ) ? sanitize_key( (string) $workflow['status'] ) : '';
        if ( 'approved' !== $workflow_status ) {
            return array(
                'success'            => false,
                'approval_required'  => true,
                'required_next_tool' => 'extension_request_create',
                'error'              => 'Remote skill import requires an approved founder self-extension workflow. First preview with external_skill_get, then open extension_request_create and wait for founder approval.',
            );
        }
        if ( ! class_exists( 'Niwa_AI_Admin_Autonomy_External_Skills' ) ) {
            return array( 'success' => false, 'error' => 'External skills runtime nije dostupan.' );
        }

        $service = new Niwa_AI_Admin_Autonomy_External_Skills();
        $preview = $service->get( $args, false );
        if ( empty( $preview['success'] ) ) {
            return $preview;
        }

        $label = isset( $preview['install_package'] ) ? (string) $preview['install_package'] : ( isset( $args['source'] ) ? (string) $args['source'] : 'remote skill' );

        return array(
            'success' => true,
            'action'  => array(
                'type'        => 'skill_import_from_github',
                'args'        => $args,
                'label'       => 'Import remote skilla "' . $label . '"',
                'description' => 'Importovace SKILL.md iz GitHub/skills.sh izvora: ' . ( isset( $preview['github_url'] ) ? (string) $preview['github_url'] : '' ),
                'risk'        => isset( $preview['risk_level'] ) ? (string) $preview['risk_level'] : 'medium',
                'trust_level' => isset( $preview['trust_level'] ) ? (string) $preview['trust_level'] : 'unknown',
                'trust_reasons' => isset( $preview['trust_reasons'] ) ? (array) $preview['trust_reasons'] : array(),
                'source'      => isset( $preview['source'] ) ? (string) $preview['source'] : '',
                'skill_path'  => isset( $preview['skill_path'] ) ? (string) $preview['skill_path'] : '',
                'content_sha256' => isset( $preview['content_sha256'] ) ? (string) $preview['content_sha256'] : '',
                'support_files_available' => isset( $preview['support_files_available'] ) ? (array) $preview['support_files_available'] : array(),
            ),
        );
    }

    private function validate_skill_import_from_github_action( $args ) {
        $args = is_array( $args ) ? $args : array();
        $source = isset( $args['source'] ) ? trim( (string) $args['source'] ) : '';
        $id     = isset( $args['id'] ) ? trim( (string) $args['id'] ) : '';
        if ( '' === $source && '' === $id ) {
            return array( 'success' => false, 'error' => 'Za GitHub skill import treba source owner/repo ili skills.sh id.' );
        }
        if ( '' !== $source && ! preg_match( '#^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$#', $source ) ) {
            return array( 'success' => false, 'error' => 'source mora biti u GitHub owner/repo formatu.' );
        }
        if ( ! class_exists( 'Niwa_AI_Admin_Autonomy_External_Skills' ) ) {
            return array( 'success' => false, 'error' => 'External skills runtime nije dostupan.' );
        }

        return array( 'success' => true );
    }

    private function execute_skill_import_from_github_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'import_skill_from_content' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        if ( ! class_exists( 'Niwa_AI_Admin_Autonomy_External_Skills' ) ) {
            return array( 'success' => false, 'error' => 'External skills runtime nije dostupan.' );
        }

        $args    = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $service = new Niwa_AI_Admin_Autonomy_External_Skills();
        $result  = $service->import_from_github( $args, $this->skills_manager );

        if ( ! empty( $result['success'] ) && isset( $result['slug'] ) ) {
            $result['rollback'] = array(
                array(
                    'type' => 'skill_delete',
                    'slug' => (string) $result['slug'],
                ),
            );
        }

        return $result;
    }

    /* ------------------------------------------------------------------
     * skill_update pipeline
     * ------------------------------------------------------------------ */

    private function preview_skill_update( $args ) {
        if ( ! $this->skills_manager ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $existing = $this->skills_manager->get_skill( $slug );
        if ( empty( $existing['success'] ) ) {
            return array( 'success' => false, 'error' => isset( $existing['error'] ) ? $existing['error'] : 'Skill ne postoji.' );
        }

        $changes = array();
        if ( isset( $args['name'] ) && '' !== trim( (string) $args['name'] ) ) {
            $changes[] = 'name';
        }
        if ( isset( $args['description'] ) && '' !== trim( (string) $args['description'] ) ) {
            $changes[] = 'description';
        }
        if ( isset( $args['content'] ) && '' !== trim( (string) $args['content'] ) ) {
            $changes[] = 'content';
        }
        if ( isset( $args['triggers'] ) && is_array( $args['triggers'] ) ) {
            $changes[] = 'triggers';
        }
        if ( isset( $args['scope'] ) && '' !== trim( (string) $args['scope'] ) ) {
            $changes[] = 'scope';
        }

        return array(
            'success'     => true,
            'type'        => 'skill_update',
            'label'       => 'Azuriranje skilla "' . ( isset( $existing['name'] ) ? $existing['name'] : $slug ) . '"',
            'description' => 'Azurira skill: ' . implode( ', ', $changes ) . '. Verzija ce biti inkrementirana.',
            'risk'        => 'low',
            'args'        => $args,
            '_previous'   => $existing,
        );
    }

    private function validate_skill_update_action( $args ) {
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        if ( '' === $slug ) {
            return array( 'success' => false, 'error' => 'Slug je obavezan za skill_update.' );
        }
        if ( isset( $args['content'] ) && strlen( (string) $args['content'] ) > 262144 ) {
            return array( 'success' => false, 'error' => 'Sadrzaj je prevelik (max 256 KB).' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_update_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'update_skill' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $name = isset( $args['name'] ) ? trim( (string) $args['name'] ) : '';
        $desc = isset( $args['description'] ) ? trim( (string) $args['description'] ) : '';
        $cont = isset( $args['content'] ) ? trim( (string) $args['content'] ) : '';

        $meta = array();
        if ( isset( $args['triggers'] ) && is_array( $args['triggers'] ) ) {
            $meta['triggers'] = $args['triggers'];
        }
        if ( isset( $args['scope'] ) && '' !== trim( (string) $args['scope'] ) ) {
            $meta['scope'] = trim( (string) $args['scope'] );
        }

        return $this->skills_manager->update_skill( $slug, $name, $desc, $cont, $meta );
    }

    /* ------------------------------------------------------------------
     * skill_eval_create pipeline
     * ------------------------------------------------------------------ */

    private function preview_skill_eval_create( $args ) {
        if ( ! $this->skills_manager ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $existing = $this->skills_manager->get_skill( $slug );
        if ( empty( $existing['success'] ) ) {
            return array( 'success' => false, 'error' => isset( $existing['error'] ) ? $existing['error'] : 'Skill ne postoji.' );
        }

        $prompt = isset( $args['prompt'] ) ? trim( (string) $args['prompt'] ) : '';
        return array(
            'success'     => true,
            'type'        => 'skill_eval_create',
            'label'       => 'Kreiranje eval-a za skill "' . ( isset( $existing['name'] ) ? $existing['name'] : $slug ) . '"',
            'description' => 'Kreira test case sa promptom: "' . mb_substr( $prompt, 0, 80 ) . ( mb_strlen( $prompt ) > 80 ? '...' : '' ) . '"',
            'risk'        => 'low',
            'args'        => $args,
        );
    }

    private function validate_skill_eval_create_action( $args ) {
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $prompt  = isset( $args['prompt'] ) ? trim( (string) $args['prompt'] ) : '';
        $expect  = isset( $args['expected_behavior'] ) ? trim( (string) $args['expected_behavior'] ) : '';
        $criteria = isset( $args['success_criteria'] ) && is_array( $args['success_criteria'] ) ? $args['success_criteria'] : array();

        if ( '' === $slug ) {
            return array( 'success' => false, 'error' => 'Slug je obavezan.' );
        }
        if ( '' === $prompt || '' === $expect || empty( $criteria ) ) {
            return array( 'success' => false, 'error' => 'Prompt, expected_behavior i success_criteria su obavezni.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_eval_create_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'create_eval' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        return $this->skills_manager->create_eval(
            isset( $args['slug'] ) ? (string) $args['slug'] : '',
            $args
        );
    }

    /* ------------------------------------------------------------------
     * skill_eval_run pipeline (LLM-as-judge)
     * ------------------------------------------------------------------ */

    private function preview_skill_eval_run( $args ) {
        if ( ! $this->skills_manager ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $existing = $this->skills_manager->get_skill( $slug );
        if ( empty( $existing['success'] ) ) {
            return array( 'success' => false, 'error' => isset( $existing['error'] ) ? $existing['error'] : 'Skill ne postoji.' );
        }

        $evals_result = $this->skills_manager->list_evals( $slug );
        $eval_count = 0;
        if ( ! empty( $evals_result['success'] ) && ! empty( $evals_result['evals'] ) ) {
            $eval_id = isset( $args['eval_id'] ) ? trim( (string) $args['eval_id'] ) : '';
            $eval_count = '' !== $eval_id ? 1 : count( $evals_result['evals'] );
        }

        if ( 0 === $eval_count ) {
            return array( 'success' => false, 'error' => 'Nema eval-ova za skill "' . $slug . '". Koristi skill_eval_create da definises test slucajeve.' );
        }

        return array(
            'success'     => true,
            'type'        => 'skill_eval_run',
            'label'       => 'Pokretanje ' . $eval_count . ' eval-a za skill "' . ( isset( $existing['name'] ) ? $existing['name'] : $slug ) . '"',
            'description' => 'Pokrece ' . $eval_count . ' eval test(ova) koristeci LLM kao sudiju. Svaki eval zahteva 2 API poziva.',
            'risk'        => 'low',
            'args'        => $args,
        );
    }

    private function validate_skill_eval_run_action( $args ) {
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        if ( '' === $slug ) {
            return array( 'success' => false, 'error' => 'Slug je obavezan.' );
        }
        if ( ! $this->eval_openai_client || ! $this->eval_auth_manager ) {
            return array( 'success' => false, 'error' => 'LLM zavisnosti nisu konfigurisane za eval operacije.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_eval_run_action( $action ) {
        if ( ! $this->skills_manager || ! $this->eval_openai_client || ! $this->eval_auth_manager || ! $this->eval_model_router ) {
            return array( 'success' => false, 'error' => 'Skills manager ili LLM zavisnosti nisu dostupne.' );
        }

        $args    = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $eval_id = isset( $args['eval_id'] ) ? trim( (string) $args['eval_id'] ) : '';

        $skill = $this->skills_manager->get_skill( $slug );
        if ( empty( $skill['success'] ) ) {
            return array( 'success' => false, 'error' => 'Skill ne postoji.' );
        }

        // Load evals
        if ( '' !== $eval_id ) {
            $eval_result = $this->skills_manager->get_eval( $slug, $eval_id );
            if ( empty( $eval_result['success'] ) ) {
                return array( 'success' => false, 'error' => isset( $eval_result['error'] ) ? $eval_result['error'] : 'Eval ne postoji.' );
            }
            $evals = array( $eval_result['eval'] );
        } else {
            $evals_result = $this->skills_manager->list_evals( $slug );
            $evals = ! empty( $evals_result['success'] ) && is_array( $evals_result['evals'] ) ? $evals_result['evals'] : array();
        }

        if ( empty( $evals ) ) {
            return array( 'success' => false, 'error' => 'Nema eval-ova za pokretanje.' );
        }

        $skill_content = isset( $skill['content'] ) ? (string) $skill['content'] : '';
        $skill_name    = isset( $skill['name'] ) ? (string) $skill['name'] : $slug;

        return $this->run_eval_suite( $slug, $skill_name, $skill_content, $evals );
    }

    private function run_eval_suite( $slug, $skill_name, $skill_content, $evals ) {
        $model     = $this->eval_model_router ? $this->eval_model_router->route_for_founder_agent() : 'gpt-5.4-mini';
        $auth_mode = $this->eval_auth_manager ? $this->eval_auth_manager->get_mode() : 'api_key';
        $creds     = $this->eval_auth_manager ? $this->eval_auth_manager->get_credentials() : array();

        $results = array();
        $pass_count = 0;

        foreach ( $evals as $eval ) {
            $eid      = isset( $eval['id'] ) ? (string) $eval['id'] : 'unknown';
            $prompt   = isset( $eval['prompt'] ) ? (string) $eval['prompt'] : '';
            $expected = isset( $eval['expected_behavior'] ) ? (string) $eval['expected_behavior'] : '';
            $criteria = isset( $eval['success_criteria'] ) && is_array( $eval['success_criteria'] ) ? $eval['success_criteria'] : array();

            if ( '' === $prompt || empty( $criteria ) ) {
                $results[] = array( 'eval_id' => $eid, 'pass' => false, 'reasoning' => 'Eval nema prompt ili success_criteria.', 'score' => 0 );
                continue;
            }

            // Step 1: Simulate agent response with skill loaded
            $sim_system = "You are an AI assistant. Follow these skill instructions:\n\n" . $skill_content . "\n\nRespond to the user's message following the skill instructions above.";
            $sim_response = $this->eval_llm_call( $sim_system, $prompt, $model, $auth_mode, $creds );

            if ( '' === $sim_response ) {
                $results[] = array( 'eval_id' => $eid, 'pass' => false, 'reasoning' => 'LLM simulacija nije vratila odgovor.', 'score' => 0 );
                continue;
            }

            // Step 2: Judge the response
            $criteria_text = implode( "\n", array_map( function( $c, $i ) { return ( $i + 1 ) . '. ' . $c; }, $criteria, array_keys( $criteria ) ) );
            $judge_system = "You are an eval judge. You evaluate whether an AI agent's response meets the specified success criteria.\n\nRespond ONLY with valid JSON: {\"pass\": true/false, \"reasoning\": \"...\", \"score\": 0-100}";
            $judge_prompt = "Skill: " . $skill_name . "\n\nUser message: " . $prompt . "\n\nExpected behavior: " . $expected . "\n\nSuccess criteria:\n" . $criteria_text . "\n\nAgent response:\n" . $sim_response . "\n\nDoes the agent response meet ALL success criteria? Return JSON verdict.";

            $judge_response = $this->eval_llm_call( $judge_system, $judge_prompt, $model, $auth_mode, $creds );
            $verdict = $this->parse_judge_verdict( $judge_response );

            if ( ! empty( $verdict['pass'] ) ) {
                $pass_count++;
            }
            $results[] = array(
                'eval_id'   => $eid,
                'pass'      => ! empty( $verdict['pass'] ),
                'reasoning' => isset( $verdict['reasoning'] ) ? (string) $verdict['reasoning'] : '',
                'score'     => isset( $verdict['score'] ) ? intval( $verdict['score'] ) : 0,
            );
        }

        $total = count( $evals );
        return array(
            'success'    => true,
            'slug'       => $slug,
            'skill_name' => $skill_name,
            'total'      => $total,
            'passed'     => $pass_count,
            'failed'     => $total - $pass_count,
            'pass_rate'  => $total > 0 ? round( ( $pass_count / $total ) * 100, 1 ) : 0,
            'results'    => $results,
            'message'    => 'Eval zavrsen: ' . $pass_count . '/' . $total . ' proslo (' . round( ( $pass_count / $total ) * 100, 1 ) . '%).',
        );
    }

    private function eval_llm_call( $system, $user_message, $model, $auth_mode, $creds ) {
        if ( ! $this->eval_openai_client ) {
            return '';
        }

        $messages = array(
            array( 'role' => 'system', 'content' => $system ),
            array( 'role' => 'user', 'content' => $user_message ),
        );

        $result = $this->eval_openai_client->chat_complete( $model, $messages, $auth_mode, $creds, 30 );

        if ( is_array( $result ) && isset( $result['content'] ) ) {
            return trim( (string) $result['content'] );
        }
        if ( is_array( $result ) && isset( $result['text'] ) ) {
            return trim( (string) $result['text'] );
        }
        if ( is_string( $result ) ) {
            return trim( $result );
        }
        return '';
    }

    private function parse_judge_verdict( $response ) {
        $response = trim( (string) $response );
        if ( '' === $response ) {
            return array( 'pass' => false, 'reasoning' => 'Prazan odgovor od sudije.', 'score' => 0 );
        }

        // Try JSON extraction
        if ( preg_match( '/\{[^{}]*"pass"\s*:\s*(true|false)[^{}]*\}/si', $response, $m ) ) {
            $decoded = json_decode( $m[0], true );
            if ( is_array( $decoded ) ) {
                return array(
                    'pass'      => ! empty( $decoded['pass'] ),
                    'reasoning' => isset( $decoded['reasoning'] ) ? (string) $decoded['reasoning'] : '',
                    'score'     => isset( $decoded['score'] ) ? intval( $decoded['score'] ) : ( ! empty( $decoded['pass'] ) ? 100 : 0 ),
                );
            }
        }

		return array(
			'pass'      => false,
			'reasoning' => 'Sudija nije vratio validan JSON ugovor: ' . mb_substr( $response, 0, 400 ),
			'score'     => 0,
		);
    }

    /* ------------------------------------------------------------------
     * skill_benchmark pipeline
     * ------------------------------------------------------------------ */

    private function preview_skill_benchmark( $args ) {
        if ( ! $this->skills_manager ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $existing = $this->skills_manager->get_skill( $slug );
        if ( empty( $existing['success'] ) ) {
            return array( 'success' => false, 'error' => isset( $existing['error'] ) ? $existing['error'] : 'Skill ne postoji.' );
        }

        $evals_result = $this->skills_manager->list_evals( $slug );
        $eval_count = ! empty( $evals_result['success'] ) && is_array( $evals_result['evals'] ) ? count( $evals_result['evals'] ) : 0;
        if ( 0 === $eval_count ) {
            return array( 'success' => false, 'error' => 'Nema eval-ova za benchmark. Koristi skill_eval_create prvo.' );
        }

        return array(
            'success'     => true,
            'type'        => 'skill_benchmark',
            'label'       => 'Benchmark skilla "' . ( isset( $existing['name'] ) ? $existing['name'] : $slug ) . '"',
            'description' => 'Poredi trenutnu verziju sa predlozenom koristeci ' . $eval_count . ' eval-a. Ukupno ' . ( $eval_count * 4 ) . ' API poziva.',
            'risk'        => 'low',
            'args'        => $args,
        );
    }

    private function validate_skill_benchmark_action( $args ) {
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $proposed = isset( $args['proposed_content'] ) ? trim( (string) $args['proposed_content'] ) : '';
        if ( '' === $slug || '' === $proposed ) {
            return array( 'success' => false, 'error' => 'Slug i proposed_content su obavezni.' );
        }
        if ( ! $this->eval_openai_client || ! $this->eval_auth_manager ) {
            return array( 'success' => false, 'error' => 'LLM zavisnosti nisu konfigurisane.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_benchmark_action( $action ) {
        if ( ! $this->skills_manager || ! $this->eval_openai_client ) {
            return array( 'success' => false, 'error' => 'Zavisnosti nisu dostupne.' );
        }

        $args     = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug     = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $proposed = isset( $args['proposed_content'] ) ? trim( (string) $args['proposed_content'] ) : '';

        $skill = $this->skills_manager->get_skill( $slug );
        if ( empty( $skill['success'] ) ) {
            return array( 'success' => false, 'error' => 'Skill ne postoji.' );
        }

        $evals_result = $this->skills_manager->list_evals( $slug );
        $evals = ! empty( $evals_result['success'] ) && is_array( $evals_result['evals'] ) ? $evals_result['evals'] : array();
        if ( empty( $evals ) ) {
            return array( 'success' => false, 'error' => 'Nema eval-ova.' );
        }

        $current_content = isset( $skill['content'] ) ? (string) $skill['content'] : '';
        $skill_name      = isset( $skill['name'] ) ? (string) $skill['name'] : $slug;

        // Run evals against current version
        $current_results = $this->run_eval_suite( $slug, $skill_name, $current_content, $evals );

        // Run evals against proposed version
        $proposed_results = $this->run_eval_suite( $slug, $skill_name . ' (proposed)', $proposed, $evals );

        $benchmark = array(
            'success'         => true,
            'slug'            => $slug,
            'skill_name'      => $skill_name,
            'current'         => array(
                'pass_rate' => isset( $current_results['pass_rate'] ) ? $current_results['pass_rate'] : 0,
                'passed'    => isset( $current_results['passed'] ) ? $current_results['passed'] : 0,
                'failed'    => isset( $current_results['failed'] ) ? $current_results['failed'] : 0,
                'results'   => isset( $current_results['results'] ) ? $current_results['results'] : array(),
            ),
            'proposed'        => array(
                'pass_rate' => isset( $proposed_results['pass_rate'] ) ? $proposed_results['pass_rate'] : 0,
                'passed'    => isset( $proposed_results['passed'] ) ? $proposed_results['passed'] : 0,
                'failed'    => isset( $proposed_results['failed'] ) ? $proposed_results['failed'] : 0,
                'results'   => isset( $proposed_results['results'] ) ? $proposed_results['results'] : array(),
            ),
            'total_evals'     => count( $evals ),
            'recommendation'  => '',
            'timestamp'       => gmdate( 'Y-m-d H:i:s' ),
        );

        $curr_rate = isset( $current_results['pass_rate'] ) ? (float) $current_results['pass_rate'] : 0;
        $prop_rate = isset( $proposed_results['pass_rate'] ) ? (float) $proposed_results['pass_rate'] : 0;

        if ( $prop_rate > $curr_rate ) {
            $benchmark['recommendation'] = 'Predlozena verzija je bolja (+' . round( $prop_rate - $curr_rate, 1 ) . '%). Preporuci se azuriranje.';
        } elseif ( $prop_rate < $curr_rate ) {
            $benchmark['recommendation'] = 'Trenutna verzija je bolja (+' . round( $curr_rate - $prop_rate, 1 ) . '%). Zadrzi trenutnu.';
        } else {
            $benchmark['recommendation'] = 'Obe verzije imaju isti pass rate (' . $curr_rate . '%). Nema jasne prednosti.';
        }

        $benchmark['message'] = 'Benchmark zavrsen. Trenutna: ' . $curr_rate . '%, Predlozena: ' . $prop_rate . '%. ' . $benchmark['recommendation'];

        // Save benchmark result
        $this->skills_manager->save_benchmark_result( $slug, $benchmark );

        return $benchmark;
    }

    /* ------------------------------------------------------------------
     * skill_optimize_description pipeline
     * ------------------------------------------------------------------ */

    private function preview_skill_optimize_description( $args ) {
        if ( ! $this->skills_manager ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $existing = $this->skills_manager->get_skill( $slug );
        if ( empty( $existing['success'] ) ) {
            return array( 'success' => false, 'error' => isset( $existing['error'] ) ? $existing['error'] : 'Skill ne postoji.' );
        }

        $sample_count   = isset( $args['sample_prompts'] ) && is_array( $args['sample_prompts'] ) ? count( $args['sample_prompts'] ) : 0;
        $negative_count = isset( $args['negative_prompts'] ) && is_array( $args['negative_prompts'] ) ? count( $args['negative_prompts'] ) : 0;

        return array(
            'success'     => true,
            'type'        => 'skill_optimize_description',
            'label'       => 'Optimizacija opisa za skill "' . ( isset( $existing['name'] ) ? $existing['name'] : $slug ) . '"',
            'description' => 'Testira ' . $sample_count . ' pozitivnih i ' . $negative_count . ' negativnih promptova, predlaze poboljsanja.',
            'risk'        => 'low',
            'args'        => $args,
        );
    }

    private function validate_skill_optimize_description_action( $args ) {
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $samples = isset( $args['sample_prompts'] ) && is_array( $args['sample_prompts'] ) ? $args['sample_prompts'] : array();
        if ( '' === $slug || empty( $samples ) ) {
            return array( 'success' => false, 'error' => 'Slug i sample_prompts su obavezni.' );
        }
        if ( ! $this->eval_openai_client || ! $this->eval_auth_manager ) {
            return array( 'success' => false, 'error' => 'LLM zavisnosti nisu konfigurisane.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_optimize_description_action( $action ) {
        if ( ! $this->skills_manager || ! $this->eval_openai_client || ! $this->eval_auth_manager || ! $this->eval_model_router ) {
            return array( 'success' => false, 'error' => 'Zavisnosti nisu dostupne.' );
        }

        $args     = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug     = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $samples  = isset( $args['sample_prompts'] ) && is_array( $args['sample_prompts'] ) ? $args['sample_prompts'] : array();
        $negatives = isset( $args['negative_prompts'] ) && is_array( $args['negative_prompts'] ) ? $args['negative_prompts'] : array();

        $skill = $this->skills_manager->get_skill( $slug );
        if ( empty( $skill['success'] ) ) {
            return array( 'success' => false, 'error' => 'Skill ne postoji.' );
        }

        $index       = $this->skills_manager->list_skills();
        $description = isset( $skill['description'] ) ? (string) $skill['description'] : '';
        $triggers    = isset( $skill['triggers'] ) && is_array( $skill['triggers'] ) ? $skill['triggers'] : array();

        // Test current matching against sample prompts
        $positive_hits = 0;
        $positive_details = array();
        foreach ( $samples as $sp ) {
            $matched = $this->skills_manager->match_skills_to_message( (string) $sp, $index );
            $hit = in_array( $slug, $matched, true );
            if ( $hit ) {
                $positive_hits++;
            }
            $positive_details[] = array( 'prompt' => (string) $sp, 'matched' => $hit );
        }

        // Test against negative prompts
        $false_positives = 0;
        $negative_details = array();
        foreach ( $negatives as $np ) {
            $matched = $this->skills_manager->match_skills_to_message( (string) $np, $index );
            $hit = in_array( $slug, $matched, true );
            if ( $hit ) {
                $false_positives++;
            }
            $negative_details[] = array( 'prompt' => (string) $np, 'false_positive' => $hit );
        }

        // Ask LLM for optimization suggestions
        $model     = $this->eval_model_router->route_for_founder_agent();
        $auth_mode = $this->eval_auth_manager->get_mode();
        $creds     = $this->eval_auth_manager->get_credentials();

        $analysis = "Skill: " . ( isset( $skill['name'] ) ? $skill['name'] : $slug ) . "\n";
        $analysis .= "Current description: " . $description . "\n";
        $analysis .= "Current triggers: [" . implode( ', ', $triggers ) . "]\n\n";
        $analysis .= "Positive prompt match results (" . $positive_hits . "/" . count( $samples ) . " matched):\n";
        foreach ( $positive_details as $d ) {
            $analysis .= "- \"" . $d['prompt'] . "\" => " . ( $d['matched'] ? 'HIT' : 'MISS' ) . "\n";
        }
        if ( ! empty( $negative_details ) ) {
            $analysis .= "\nNegative prompt results (" . $false_positives . " false positives):\n";
            foreach ( $negative_details as $d ) {
                $analysis .= "- \"" . $d['prompt'] . "\" => " . ( $d['false_positive'] ? 'FALSE POSITIVE' : 'OK' ) . "\n";
            }
        }

        $optimize_system = "You are a skill optimization expert. Analyze the matching results and suggest improved description and trigger keywords.\n\nRespond with JSON: {\"suggested_description\": \"...\", \"suggested_triggers\": [\"...\"], \"reasoning\": \"...\"}";

        $suggestion_response = $this->eval_llm_call( $optimize_system, $analysis, $model, $auth_mode, $creds );
        $suggestion = array( 'suggested_description' => '', 'suggested_triggers' => array(), 'reasoning' => '' );
        if ( preg_match( '/\{[^{}]*"suggested_description"[^{}]*\}/si', $suggestion_response, $m ) ) {
            $decoded = json_decode( $m[0], true );
            if ( is_array( $decoded ) ) {
                $suggestion = $decoded;
            }
        }

        return array(
            'success'           => true,
            'slug'              => $slug,
            'current'           => array(
                'description' => $description,
                'triggers'    => $triggers,
            ),
            'matching_results'  => array(
                'positive_hit_rate'  => count( $samples ) > 0 ? round( ( $positive_hits / count( $samples ) ) * 100, 1 ) : 0,
                'positive_details'   => $positive_details,
                'false_positive_count' => $false_positives,
                'negative_details'   => $negative_details,
            ),
            'suggestions'       => $suggestion,
            'message'           => 'Optimizacija zavrsena. Predlozi su dostupni (nisu automatski primenjeni). Koristi skill_update da primenis.',
        );
    }

    /* ------------------------------------------------------------------
     * skill_file_write pipeline
     * ------------------------------------------------------------------ */

    private function preview_skill_file_write( $args ) {
        if ( ! $this->skills_manager ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }
        $slug = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $path = isset( $args['path'] ) ? trim( (string) $args['path'] ) : '';
        $content_size = isset( $args['content'] ) ? strlen( (string) $args['content'] ) : 0;

        $existing = $this->skills_manager->get_skill( $slug );
        if ( empty( $existing['success'] ) ) {
            return array( 'success' => false, 'error' => isset( $existing['error'] ) ? $existing['error'] : 'Skill ne postoji.' );
        }

        return array(
            'success'     => true,
            'type'        => 'skill_file_write',
            'label'       => 'Upis fajla "' . $path . '" u skill "' . $slug . '"',
            'description' => 'Upisuje ' . round( $content_size / 1024, 1 ) . ' KB u ' . $path,
            'risk'        => 'low',
            'args'        => $args,
        );
    }

    private function validate_skill_file_write_action( $args ) {
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $path    = isset( $args['path'] ) ? trim( (string) $args['path'] ) : '';
        $content = isset( $args['content'] ) ? (string) $args['content'] : '';

        if ( '' === $slug || '' === $path || '' === $content ) {
            return array( 'success' => false, 'error' => 'Slug, path i content su obavezni.' );
        }
        if ( strlen( $content ) > 131072 ) {
            return array( 'success' => false, 'error' => 'Fajl je prevelik (max 128 KB).' );
        }
        // Validate path starts with allowed subdir
        $parts = explode( '/', str_replace( '\\', '/', $path ) );
        $subdir = isset( $parts[0] ) ? strtolower( $parts[0] ) : '';
        if ( ! in_array( $subdir, array( 'references', 'scripts', 'assets' ), true ) ) {
            return array( 'success' => false, 'error' => 'Putanja mora pocinjati sa references/, scripts/ ili assets/.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_file_write_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'write_skill_file' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args    = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $path    = isset( $args['path'] ) ? trim( (string) $args['path'] ) : '';
        $content = isset( $args['content'] ) ? (string) $args['content'] : '';

        return $this->skills_manager->write_skill_file( $slug, $path, $content );
    }

    private function preview_skill_file_edit_patch( $args ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'read_skill_file' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $path    = isset( $args['path'] ) ? trim( (string) $args['path'] ) : '';
        $patches = isset( $args['patches'] ) && is_array( $args['patches'] ) ? $args['patches'] : array();

        if ( '' === $slug || '' === $path || empty( $patches ) ) {
            return array( 'success' => false, 'error' => 'Slug, path i patches su obavezni.' );
        }
        if ( count( $patches ) > 20 ) {
            return array( 'success' => false, 'error' => 'Maksimalno 20 patch-eva po operaciji.' );
        }

        $file = $this->skills_manager->read_skill_file( $slug, $path );
        if ( empty( $file['success'] ) ) {
            return $file;
        }

        $working  = isset( $file['content'] ) ? (string) $file['content'] : '';
        $previews = array();
        foreach ( $patches as $idx => $patch ) {
            if ( ! is_array( $patch ) ) {
                return array( 'success' => false, 'error' => 'Patch #' . ( $idx + 1 ) . ' nije validan objekat.' );
            }
            $window = $this->build_patch_scope_window( $working, $patch );
            if ( empty( $window['success'] ) ) {
                return $window;
            }
            $applied = $this->apply_single_text_patch( $window['scope'], $patch, $idx );
            if ( empty( $applied['success'] ) ) {
                return $applied;
            }
            $working = $window['prefix'] . $applied['updated_scope'] . $window['suffix'];
            $preview = isset( $applied['preview'] ) && is_array( $applied['preview'] ) ? $applied['preview'] : array();
            $preview['start_line'] = intval( isset( $window['start_line'] ) ? $window['start_line'] : 1 );
            $preview['end_line']   = intval( isset( $window['end_line'] ) ? $window['end_line'] : max( 1, $preview['start_line'] ) );
            $previews[]            = $preview;
        }

        return array(
            'success' => true,
            'action'  => array(
                'type'    => 'skill_file_edit_patch',
                'label'   => 'Patch skill fajla "' . $path . '"',
                'summary' => 'Menja fajl ' . $path . ' u skill-u "' . $slug . '" (' . count( $patches ) . ' patch-eva).',
                'risk'    => 'low',
                'args'    => array(
                    'slug'         => $slug,
                    'path'         => $path,
                    'content'      => $working,
                    'content_hash' => md5( isset( $file['content'] ) ? (string) $file['content'] : '' ),
                ),
            ),
            'previews' => $previews,
        );
    }

    private function validate_skill_file_edit_patch_action( $args ) {
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $path    = isset( $args['path'] ) ? trim( (string) $args['path'] ) : '';
        $content = isset( $args['content'] ) ? (string) $args['content'] : '';
        if ( '' === $slug || '' === $path || '' === $content ) {
            return array( 'success' => false, 'error' => 'Slug, path i content su obavezni.' );
        }
        return array( 'success' => true );
    }

    private function execute_skill_file_edit_patch_action( $action ) {
        if ( ! $this->skills_manager || ! method_exists( $this->skills_manager, 'read_skill_file' ) || ! method_exists( $this->skills_manager, 'write_skill_file' ) ) {
            return array( 'success' => false, 'error' => 'Skills manager nije dostupan.' );
        }

        $args    = isset( $action['args'] ) && is_array( $action['args'] ) ? $action['args'] : array();
        $slug    = isset( $args['slug'] ) ? trim( (string) $args['slug'] ) : '';
        $path    = isset( $args['path'] ) ? trim( (string) $args['path'] ) : '';
        $content = isset( $args['content'] ) ? (string) $args['content'] : '';

        $current = $this->skills_manager->read_skill_file( $slug, $path );
        if ( empty( $current['success'] ) ) {
            return $current;
        }
        $expected_hash = isset( $args['content_hash'] ) ? (string) $args['content_hash'] : '';
        if ( '' !== $expected_hash && md5( isset( $current['content'] ) ? (string) $current['content'] : '' ) !== $expected_hash ) {
            return array( 'success' => false, 'error' => 'Skill fajl je izmenjen nakon preview-a. Ponovi operaciju.' );
        }

        return $this->skills_manager->write_skill_file( $slug, $path, $content );
    }
}
