<?php
/**
 * Admin Chat Controller V1
 *
 * @package ZenoChatbot\Http\Controller\Api\V1
 */

namespace ZenoChatbot\Http\Controller\Api\V1;

use ZenoChatbot\Framework\Http\Request;
use ZenoChatbot\Model\Conversation;
use ZenoChatbot\Helper\Email;
use ZenoChatbot\Helper\Security;
use ZenoChatbot\Model\Message;
use ZenoChatbot\Services\ConversationLifecycleService;
use ZenoChatbot\Support\Hooks;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Admin chat management API controller
 */
class AdminChatController
{


    /**
     * Get a conversation list with customer info and message counts
     *
     * @param Request $request
     * @return array
     */
    public function index(Request $request)
    {

        $filters = $request->getSafe([
            'search' => 'sanitize_text_field',
            'status' => 'sanitize_text_field'
        ]);

        $conversations = Conversation::query()
            ->filterBy($filters)
            ->with(['customer'])
            ->withCount(['messages'])
            ->select(['id', 'customer_id', 'department', 'started_at', 'ended_at', 'total_tokens', 'created_at', 'updated_at'])
            ->orderBy('started_at', 'desc')
            ->paginate()
        ;

        return [
            'success'       => true,
            'conversations' => $conversations,
            'filters'       => $filters
        ];
    }

    /**
     * Get specific conversation with messages and customer info
     *
     * @param $id
     * @return array
     * @throws \Exception
     */
    public function show($id)
    {

        $conversation = Conversation::query()
            ->with(['customer', 'messages'])
            ->findOrFail($id)
        ;

        $summaryState = ConversationLifecycleService::getSummaryState((int) $conversation->id);
        $conversation->summary_status = $summaryState['status'];
        $conversation->summary_generated_at = $summaryState['generated_at'];
        $conversation->summary_message_id = $summaryState['message_id'];
        $conversation->summary_text = $summaryState['text'];

        return [
            'success'      => true,
            'conversation' => $conversation
        ];
    }

    /**
     * Update conversation status (close/reopen)
     *
     * @param $id
     * @param Request $request
     * @return array
     * @throws \Exception
     */
    public function updateStatus($id, Request $request)
    {
        $status = $request->getSafe('status', 'sanitize_text_field');

        if (!in_array($status, ['open', 'closed'])) {
            return [
                'success' => false,
                'message' => 'Invalid status. Must be "open" or "closed"',
                'status'  => 400,
                'data'    => $request->all()
            ];
        }

        // Find conversation
        $conversation = Conversation::query()->findOrFail($id);
        $wasClosed = !empty($conversation->ended_at);

        $conversation->update([
            'ended_at' => $status === 'closed' ? current_time('mysql') : null,
            'status' => $status,
        ]);

        $oldStatus = $wasClosed ? 'closed' : 'open';
        Hooks::doAction(Hooks::CONVERSATION_STATUS_CHANGED, ['conversation' => $conversation, 'old_status' => $oldStatus, 'new_status' => $status]);

        if ($status === 'closed' && !$wasClosed) {
            // Summary runs as a background job; response carries status 'pending'
            ConversationLifecycleService::requestSummaryGeneration((int) $conversation->id, 'admin_close', 'admin');
        }

        $summaryState = ConversationLifecycleService::getSummaryState((int) $conversation->id);
        $conversation->summary_status = $summaryState['status'];
        $conversation->summary_generated_at = $summaryState['generated_at'];
        $conversation->summary_message_id = $summaryState['message_id'];
        $conversation->summary_text = $summaryState['text'];

        return [
            'success'      => true,
            'message'      => 'Conversation status updated successfully',
            'conversation' => $conversation
        ];
    }

    /**
     * Send reply to customer via email
     *
     * @param $id
     * @param Request $request
     * @return array
     * @throws \Exception
     */
    public function sendReply($id, Request $request)
    {

        $message = $request->getSafe('message', 'sanitize_textarea_field');
        $resolve = (bool) $request->input('resolve');

        if (empty($message)) {
            return [
                'success' => false,
                'message' => 'Reply message is required',
                'status'  => 400
            ];
        }

        $conversation = Conversation::query()
            ->with(['customer', 'messages'])
            ->findOrFail($id)
        ;

        $customer = $conversation->customer;

        if (!$customer || empty($customer->email)) {
            return [
                'success' => false,
                'message' => 'Customer email not found',
                'status'  => 400
            ];
        }

        $this->sendCustomerEmail($customer->email, $message);

        $messageData = [
            'conversation_id' => $id,
            'sender_type'     => 'agent',
            'sender_id'       => get_current_user_id(),
            'message'         => $message,
            'sent_via'        => 'email',
            'created_at'      => current_time('mysql')
        ];

        $messageId = Message::query()->insert($messageData);

        Hooks::doAction(Hooks::CONVERSATION_REPLY_SENT, ['conversation' => $conversation, 'message_id' => (int) $messageId]);

        if ($resolve) {
            $conversation->update([
                'ended_at' => current_time('mysql'),
                'status' => 'closed',
            ]);
            ConversationLifecycleService::requestSummaryGeneration((int) $conversation->id, 'admin_close', 'admin');
        }

        return [
            'success' => true,
            'message' => 'Reply sent successfully',
            'data'    => [
                'message_id' => $messageId
            ]
        ];
    }

    /**
     * Delete conversation and its messages
     *
     * @param $id
     * @return array
     */
    public function destroy($id)
    {
        try {
            $conversation = Conversation::query()->findOrFail($id);
            $conversation->messages()->delete();
            $conversation->delete();

            Hooks::doAction(Hooks::CONVERSATION_DELETED, (int) $id);

            return [
                'success' => true,
                'message' => 'Conversation deleted successfully'
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to delete conversation',
                'error'   => WP_DEBUG ? $e->getMessage() : 'Internal server error',
                'status'  => 500
            ];
        }
    }


    /**
     * Send email to customer with reply and conversation context
     *
     * @param $customerEMail
     * @param $message
     * @return array
     * @throws \Exception
     */
    private function sendCustomerEmail($customerEMail, $message)
    {
        return Email::sendCustomerReply([
            'email'   => $customerEMail,
            'message' => $message
        ]);
    }

    /**
     * Generate summary synchronously for a conversation.
     *
     * @param int|string $id
     * @param Request $request
     * @return array
     */
    public function generateSummary($id, Request $request)
    {
        if (!Security::currentUserCan('manage_options')) {
            return [
                'success' => false,
                'message' => 'Insufficient permissions',
                'status' => 403,
            ];
        }

        $mode = sanitize_key((string) $request->getSafe('mode', 'sanitize_text_field'));
        if (!in_array($mode, ['retry', 'regenerate'], true)) {
            return [
                'success' => false,
                'message' => 'Invalid mode. Must be "retry" or "regenerate".',
                'status' => 400,
            ];
        }

        $conversation = Conversation::query()->findOrFail((int) $id);

        $result = ConversationLifecycleService::generateOnDemandSync((int) $conversation->id, $mode);
        $summaryState = ConversationLifecycleService::getSummaryState((int) $conversation->id);

        if (empty($result['success'])) {
            return [
                'success' => false,
                'message' => 'Failed to generate summary.',
                'status' => 500,
                'data' => [
                    'summary_status' => $summaryState['status'],
                    'summary_generated_at' => $summaryState['generated_at'],
                    'summary_message_id' => $summaryState['message_id'],
                    'summary_text' => $summaryState['text'],
                    'error_code' => (string) ($result['error_code'] ?? 'summary_generation_failed'),
                ],
            ];
        }

        return [
            'success' => true,
            'message' => !empty($result['skipped']) ? 'Summary generation skipped.' : 'Summary generated successfully.',
            'data' => [
                'summary_status' => $summaryState['status'],
                'summary_generated_at' => $summaryState['generated_at'],
                'summary_message_id' => $summaryState['message_id'],
                'summary_text' => $summaryState['text'],
            ],
        ];
    }
}
