<?php
/**
 * Conversation REST Controller
 *
 * Handles conversation CRUD operations.
 *
 * @package WP_Agentic_Writer
 */

/**
 * Class WP_Agentic_Writer_Controller_Conversation
 *
 * REST controller for conversation operations.
 *
 * @since 0.3.0
 */
class WP_Agentic_Writer_Controller_Conversation {

    /**
     * Sidebar instance for dependency access.
     *
     * @var WP_Agentic_Writer_Gutenberg_Sidebar
     */
    private $sidebar;

    /**
     * Constructor.
     *
     * @since 0.3.0
     * @param WP_Agentic_Writer_Gutenberg_Sidebar $sidebar Sidebar instance.
     */
    public function __construct( $sidebar ) {
        $this->sidebar = $sidebar;
    }

    /**
     * Handle get conversations request.
     *
     * Lists all conversations for the current user, optionally filtered by post.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_get_conversations( $request ) {
        $manager = WP_Agentic_Writer_Conversation_Manager::get_instance();

        $status  = sanitize_text_field( $request->get_param( 'status' ) ?: 'active' );
        $limit   = (int) $request->get_param( 'limit' ) ?: 20;
        $post_id = (int) $request->get_param( 'post_id' ) ?: 0;

        // If post_id is specified, check authorization before returning session.
        if ( $post_id > 0 ) {
            // Authorization: User must be able to edit this post.
            if ( ! current_user_can( 'edit_post', $post_id ) ) {
                return new WP_Error(
                    'forbidden',
                    __(
                        'You do not have permission to access this post.',
                        'wp-agentic-writer',
                    ),
                    [ 'status' => 403 ],
                );
            }

            $sessions = $manager->get_sessions_for_post( $post_id );
            return new WP_REST_Response(
                [
                    'sessions' => $sessions,
                    'count'    => count( $sessions ),
                ],
                200,
            );
        }

        if ( $request->get_param( 'uncompleted' ) ) {
            $sessions = $manager->get_uncompleted_sessions( $limit );
        } else {
            $sessions = $manager->get_user_sessions( $status, $limit );
        }

        return new WP_REST_Response(
            [
                'sessions' => $sessions,
                'count'    => count( $sessions ),
            ],
            200,
        );
    }

    /**
     * Handle create conversation request.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_create_conversation( $request ) {
        $params  = $request->get_json_params();
        $manager = WP_Agentic_Writer_Conversation_Manager::get_instance();

        $post_id       = isset( $params['post_id'] ) ? (int) $params['post_id'] : 0;
        $focus_keyword = isset( $params['focus_keyword'] )
            ? sanitize_text_field( $params['focus_keyword'] )
            : '';
        $title         = isset( $params['title'] )
            ? sanitize_text_field( $params['title'] )
            : '';

        // Authorization: If linking to a post, check edit permission.
        if ( $post_id > 0 && ! current_user_can( 'edit_post', $post_id ) ) {
            return new WP_Error(
                'forbidden',
                __(
                    'You do not have permission to create a session for this post.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        if ( '' === $title && $post_id > 0 ) {
            $post      = get_post( $post_id );
            $base_title = $post ? sanitize_text_field( $post->post_title ) : '';
            if ( '' === $base_title ) {
                $base_title = 'Conversation';
            }
            $title = sprintf( '%s - %s', $base_title, current_time( 'Y-m-d H:i' ) );
        }

        $session_id = $manager->create_session(
            [
                'post_id'       => $post_id,
                'focus_keyword' => $focus_keyword,
                'title'         => $title,
            ]
        );

        if ( is_wp_error( $session_id ) ) {
            return $session_id;
        }

        $session = $manager->get_session( $session_id );

        // MEMANTO: New session created.
        do_action(
            'wpaw_memanto_session_start',
            $session_id,
            $post_id,
            get_current_user_id(),
        );

        return new WP_REST_Response( $session, 201 );
    }

    /**
     * Handle get single conversation request.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_get_conversation( $request ) {
        $session_id = sanitize_text_field( $request->get_param( 'session_id' ) );
        $manager    = WP_Agentic_Writer_Conversation_Manager::get_instance();

        // Check authorization.
        if ( ! $manager->current_user_can_access( $session_id ) ) {
            return new WP_Error(
                'forbidden',
                __(
                    'You do not have permission to access this conversation.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        $session = $manager->get_session( $session_id );

        if ( ! $session ) {
            return new WP_Error(
                'not_found',
                __( 'Conversation not found.', 'wp-agentic-writer' ),
                [ 'status' => 404 ],
            );
        }

        $session = $this->hydrate_session_plan_messages( $session );

        return new WP_REST_Response( $session, 200 );
    }

    /**
     * Restore rich plan UI payloads for sessions that only stored a text summary.
     *
     * @since 0.2.2
     * @param array $session Conversation session.
     * @return array
     */
    private function hydrate_session_plan_messages( $session ) {
        if ( ! is_array( $session ) ) {
            return $session;
        }

        $post_id = isset( $session['post_id'] ) ? (int) $session['post_id'] : 0;
        if (
            $post_id <= 0
            || empty( $session['messages'] )
            || ! is_array( $session['messages'] )
        ) {
            return $session;
        }

        foreach ( $session['messages'] as $message ) {
            if (
                isset( $message['type'] )
                && 'plan' === $message['type']
                && ! empty( $message['plan'] )
            ) {
                return $session;
            }
        }

        $plan = get_post_meta( $post_id, '_wpaw_plan', true );
        if ( ! is_array( $plan ) ) {
            return $session;
        }

        foreach ( $session['messages'] as $index => $message ) {
            $content = isset( $message['content'] )
                ? (string) $message['content']
                : '';
            $role = isset( $message['role'] ) ? (string) $message['role'] : '';
            if (
                'assistant' !== $role
                || false === strpos( $content, 'Outline ready.' )
            ) {
                continue;
            }

            $session['messages'][ $index ]['type'] = 'plan';
            $session['messages'][ $index ]['plan']   = $plan;
            break;
        }

        return $session;
    }

    /**
     * Handle update conversation request.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_update_conversation( $request ) {
        $params     = $request->get_json_params();
        $session_id = sanitize_text_field( $request->get_param( 'session_id' ) );
        $manager    = WP_Agentic_Writer_Conversation_Manager::get_instance();

        // Check authorization.
        if ( ! $manager->current_user_can_access( $session_id ) ) {
            return new WP_Error(
                'forbidden',
                __(
                    'You do not have permission to modify this conversation.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        $session = $manager->get_session( $session_id );

        if ( ! $session ) {
            return new WP_Error(
                'not_found',
                __( 'Conversation not found.', 'wp-agentic-writer' ),
                [ 'status' => 404 ],
            );
        }

        // Update fields.
        if ( isset( $params['title'] ) ) {
            $manager->update_title( $session_id, $params['title'] );
        }

        if ( isset( $params['focus_keyword'] ) ) {
            $manager->update_focus_keyword(
                $session_id,
                $params['focus_keyword'],
            );
        }

        if ( isset( $params['status'] ) ) {
            if ( 'completed' === $params['status'] ) {
                $manager->mark_completed( $session_id );

                // MEMANTO: Session completed.
                $post_id = $session['post_id'] ?? 0;
                do_action(
                    'wpaw_memanto_session_end',
                    $session_id,
                    (int) $post_id,
                );
            }
        }

        $updated_session = $manager->get_session( $session_id );

        return new WP_REST_Response( $updated_session, 200 );
    }

    /**
     * Handle delete conversation request.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_delete_conversation( $request ) {
        $session_id = sanitize_text_field( $request->get_param( 'session_id' ) );
        $manager    = WP_Agentic_Writer_Conversation_Manager::get_instance();

        // Check authorization.
        if ( ! $manager->current_user_can_access( $session_id ) ) {
            return new WP_Error(
                'forbidden',
                __(
                    'You do not have permission to delete this conversation.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        $result = $manager->delete_session( $session_id );

        if ( ! $result ) {
            return new WP_Error(
                'delete_failed',
                __( 'Failed to delete conversation.', 'wp-agentic-writer' ),
                [ 'status' => 500 ],
            );
        }

        // MEMANTO: Session deleted — treat as session end.
        $session = $manager->get_session_unchecked( $session_id );
        $post_id = $session ? $session['post_id'] ?? 0 : 0;
        do_action( 'wpaw_memanto_session_end', $session_id, (int) $post_id );

        return new WP_REST_Response( [ 'deleted' => true ], 200 );
    }

    /**
     * Handle update conversation messages request.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_update_conversation_messages( $request ) {
        $params     = $request->get_json_params();
        $session_id = sanitize_text_field( $request->get_param( 'session_id' ) );
        $manager    = WP_Agentic_Writer_Conversation_Manager::get_instance();

        // Check authorization.
        if ( ! $manager->current_user_can_access( $session_id ) ) {
            return new WP_Error(
                'forbidden',
                __(
                    'You do not have permission to modify this conversation.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        $session = $manager->get_session( $session_id );

        if ( ! $session ) {
            return new WP_Error(
                'not_found',
                __( 'Conversation not found.', 'wp-agentic-writer' ),
                [ 'status' => 404 ],
            );
        }

        $messages = isset( $params['messages'] ) ? $params['messages'] : [];

        if ( ! is_array( $messages ) ) {
            return new WP_Error(
                'invalid_messages',
                __( 'Messages must be an array.', 'wp-agentic-writer' ),
                [ 'status' => 400 ],
            );
        }

        // Safety: refuse to overwrite existing messages with an empty array.
        // This prevents race conditions during session switches from wiping
        // conversation history. Intentional clears go through clear-context.
        $existing_count = count( $session['messages'] ?? [] );
        if ( empty( $messages ) && $existing_count > 0 ) {
            return new WP_REST_Response(
                [
                    'updated'       => false,
                    'message_count' => $existing_count,
                    'skipped'       => 'empty_overwrite_blocked',
                ],
                200,
            );
        }

        $updated = $manager->update_messages( $session_id, $messages );
        if ( ! $updated ) {
            return new WP_Error(
                'message_update_failed',
                __(
                    'Failed to update conversation messages.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 500 ],
            );
        }

        return new WP_REST_Response(
            [ 'updated' => true, 'message_count' => count( $messages ) ],
            200,
        );
    }

    /**
     * Handle link conversation to post request.
     *
     * @since 0.1.4
     * @param WP_REST_Request $request REST request.
     * @return WP_REST_Response|WP_Error
     */
    public function handle_link_conversation_to_post( $request ) {
        $params     = $request->get_json_params();
        $session_id = sanitize_text_field( $request->get_param( 'session_id' ) );
        $manager    = WP_Agentic_Writer_Conversation_Manager::get_instance();

        // First verify user has access to this session (before linking to post).
        if ( ! $manager->current_user_can_access( $session_id ) ) {
            return new WP_Error(
                'forbidden',
                __(
                    'You do not have access to this conversation.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        $session = $manager->get_session( $session_id );

        if ( ! $session ) {
            return new WP_Error(
                'not_found',
                __( 'Conversation not found.', 'wp-agentic-writer' ),
                [ 'status' => 404 ],
            );
        }

        $post_id = isset( $params['post_id'] ) ? (int) $params['post_id'] : 0;

        if ( $post_id <= 0 ) {
            return new WP_Error(
                'invalid_post',
                __( 'Valid post ID is required.', 'wp-agentic-writer' ),
                [ 'status' => 400 ],
            );
        }

        // Verify post exists and user can edit.
        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return new WP_Error(
                'permission_denied',
                __(
                    'You do not have permission to edit this post.',
                    'wp-agentic-writer',
                ),
                [ 'status' => 403 ],
            );
        }

        $manager->link_to_post( $session_id, $post_id );

        $updated_session = $manager->get_session( $session_id );

        return new WP_REST_Response(
            [
                'linked'  => true,
                'post_id' => $post_id,
                'session' => $updated_session,
            ],
            200,
        );
    }
}
