<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import {
    Card,
    Typography,
    Button,
    List,
    Space,
    Spin,
    Input,
    message,
    Tag,
    InputNumber,
    Select,
    Tooltip,
} from 'ant-design-vue'
import { useAgentStore } from '../stores/agentStore'
import { apiClient, isAxiosError, API } from '../router/api'
import type { AgentConfig, AgentRunResult } from '../types/agent'
import { InfoCircleOutlined } from '@ant-design/icons-vue'

const route = useRoute()
const agentStore = useAgentStore()

const agentUuid = route.params.agentUuid as string

const agent = ref<AgentConfig>({
    name: 'Loading...',
    status: 'idle',
    uuid: agentUuid,
    agent_type: 'knowledge',
    llm_config: {},
    organization: '',
})
const saveLoading = ref(false)
const editingConfig = ref(false)
const agentForm = ref({
    name: '',
    agent_type: 'knowledge',
    model_id: '',
    system_prompt: '',
})

const agentTypeOptions = [
    { label: 'Curriculum Agent', value: 'curriculum' },
    { label: 'Knowledge Agent', value: 'knowledge' },
    { label: 'Assessment Agent', value: 'assessment' },
    { label: 'Progress Monitor', value: 'monitor' },
]
const maxTokens = ref<number>(256)

const queryInput = ref('')
const isRunning = computed(() => agentStore.executionStatus === 'running')
const isConnected = computed(() => agentStore.isConnected ?? false)

const agentResponse = computed(() => {
    const completedEvent = agentStore.eventLog?.find((event) => event.type === 'completed')
    if (completedEvent?.content && typeof completedEvent.content === 'object') {
        const output = completedEvent.content as AgentRunResult

        return (output.response as string) || null
    }
    return null
})

const statusColor = (status: string) => {
    const colors: Record<string, string> = {
        idle: 'default',
        running: 'processing',
        completed: 'success',
        failed: 'error',
        stopped: 'warning',
    }
    return colors[status] || 'default'
}

const fetchAgent = async () => {
    try {
        const response = await apiClient.get<AgentConfig>(API.agents.configs.byId(agentUuid))
        agent.value = response.data
        agentForm.value = {
            name: response.data.name || '',
            agent_type: response.data.agent_type || 'knowledge',
            model_id: String(response.data.llm_config?.model_id || ''),
            system_prompt: String(response.data.system_prompt || ''),
        }
    } catch (error) {
        console.error('Failed to fetch agent:', error)
        if (isAxiosError(error)) {
            console.error('Axios error details:', {
                status: error.response?.status,
                data: error.response?.data,
                message: error.message,
            })
        }
        message.error('Failed to load agent details')
    }
}

const resetForm = () => {
    agentForm.value = {
        name: agent.value.name || '',
        agent_type: agent.value.agent_type || 'knowledge',
        model_id: String(agent.value.llm_config?.model_id || ''),
        system_prompt: String(agent.value.system_prompt || ''),
    }
    editingConfig.value = false
}

const saveConfig = async () => {
    const payload = {
        name: agentForm.value.name.trim(),
        system_prompt: agentForm.value.system_prompt.trim(),
    }

    if (!payload.name) {
        message.error('Agent name is required')
        return
    }

    if (!payload.system_prompt) {
        message.error('System prompt is required')
        return
    }

    saveLoading.value = true
    try {
        const response = await apiClient.patch<AgentConfig>(API.agents.configs.byId(agentUuid), payload)
        agent.value = response.data
        editingConfig.value = false
        message.success('Agent configuration updated')
    } catch (error) {
        console.error('Failed to update agent config:', error)
        if (isAxiosError(error)) {
            message.error(error.response?.data?.detail || 'Failed to update configuration')
        } else {
            message.error('Failed to update configuration')
        }
    } finally {
        saveLoading.value = false
    }
}

const displayedResponse = computed(() => agentResponse.value || agentStore.streamBuffer || '')

const startAgent = () => {
    if (!agentStore.isConnected) {
        message.error('WebSocket not connected')
        return
    }

    if (!queryInput.value.trim()) {
        message.error('Please enter a query')
        return
    }

    agentStore.startAgent({
        query: queryInput.value.trim(),
        max_tokens: maxTokens.value,
    })
}

const stopAgent = () => {
    agentStore.stopAgent(agentStore.lastExecutionId || undefined)
    message.success('Agent stop requested')
}

onMounted(() => {
    fetchAgent()
    agentStore.connect(agentUuid)
})

onUnmounted(() => {
    agentStore.disconnect()
})
</script>

<template>
    <div class="page">
        <Card class="panel" :bordered="false">
            <div class="header">
                <Typography.Title :level="2">{{ agent.name }}</Typography.Title>
                <Tag :color="statusColor(String(agentStore.executionStatus || 'idle'))">
                    {{ (agentStore.executionStatus || 'idle').toString().toUpperCase() }}
                </Tag>
            </div>

            <Typography.Title :level="4" class="section-title">Configuration</Typography.Title>
            <div class="execution-controls">
                <Space direction="vertical" style="width: 100%" :size="12">
                    <div>
                        <Typography.Text>Agent Name:</Typography.Text>
                        <Input v-model:value="agentForm.name" :disabled="!editingConfig" />
                    </div>

                    <div>
                        <Typography.Text>Agent Type:</Typography.Text>
                        <Select
                            v-model:value="agentForm.agent_type"
                            :options="agentTypeOptions"
                            disabled
                            style="width: 100%"
                        />
                    </div>

                    <div>
                        <Typography.Text>Model ID:</Typography.Text>
                        <Input v-model:value="agentForm.model_id" disabled />
                    </div>

                    <div>
                        <Typography.Text>System Prompt:</Typography.Text>
                        <Input.TextArea
                            v-model:value="agentForm.system_prompt"
                            :rows="6"
                            :disabled="!editingConfig"
                        />
                    </div>

                    <Space>
                        <Button v-if="!editingConfig" type="primary" @click="editingConfig = true">
                            Edit Configuration
                        </Button>
                        <template v-else>
                            <Button type="primary" :loading="saveLoading" @click="saveConfig">
                                Save Changes
                            </Button>
                            <Button @click="resetForm">Cancel</Button>
                        </template>
                    </Space>
                </Space>
            </div>

            <div class="connection-status">
                <span>WebSocket Status:</span>
                <Tag :color="agentStore.isConnected ? 'green' : 'red'">
                    {{ agentStore.isConnected ? 'CONNECTED' : 'DISCONNECTED' }}
                </Tag>
            </div>

            <Typography.Title :level="4" class="section-title">Execution</Typography.Title>

            <div class="execution-controls">
                <Space direction="vertical" style="width: 100%">
                    <div>
                        <Typography.Text>Query:</Typography.Text>
                        <Input.TextArea
                            v-model:value="queryInput"
                            :disabled="isRunning"
                            placeholder="Enter your query here..."
                            :rows="4"
                        />
                    </div>

                    <div>
                        <Space :size="4" align="center" style="margin-bottom: 4px">
                            <Typography.Text>Max Tokens</Typography.Text>
                            <Tooltip title="The maximum number of tokens the agent can generate in a single response. One token ≈ 4 characters. If the response cuts off mid-sentence, increase this value.">
                                <InfoCircleOutlined style="color: #9ca3af; cursor: help" />
                            </Tooltip>
                        </Space>
                        <InputNumber
                            v-model:value="maxTokens"
                            :min="1"
                            :max="4096"
                            :disabled="isRunning"
                            style="width: 100%"
                        />
                    </div>

                    <Space>
                        <Button
                            type="primary"
                            :disabled="isRunning || !isConnected"
                            @click="startAgent"
                        >
                            Run Agent
                        </Button>
                        <Button danger :disabled="!isRunning" @click="stopAgent">Stop Agent</Button>
                    </Space>
                </Space>
            </div>

            <div v-if="agentResponse || agentStore.streamBuffer" class="response-section">
                <Typography.Title :level="4" class="section-title">
                    {{ agentStore.streamBuffer && !agentResponse ? 'Response' : 'Final Response' }}
                </Typography.Title>
                <Card class="response-card response-final" :bordered="false">
                    <Typography.Text>{{ displayedResponse }}</Typography.Text>
                </Card>
            </div>
            <Typography.Title :level="4" class="section-title">Execution Log</Typography.Title>

            <Spin :spinning="isRunning" tip="Agent running...">
                <div class="log-container">
                    <List
                        v-if="(agentStore.eventLog?.length ?? 0) > 0"
                        :data-source="agentStore.eventLog || []"
                        :bordered="false"
                    >
                        <template #renderItem="{ item }">
                            <List.Item class="log-item">
                                <div class="log-entry">
                                    <Tag class="log-type">{{ item.type }}</Tag>
                                    <span class="log-time">
                                        {{ item.timestamp.toLocaleTimeString() }}
                                    </span>
                                    <div v-if="item.message" class="log-message">
                                        {{ item.message }}
                                    </div>
                                    <div
                                        v-if="item.content && typeof item.content === 'object'"
                                        class="log-content"
                                    >
                                        <pre>{{ JSON.stringify(item.content, null, 2) }}</pre>
                                    </div>
                                    <div v-else-if="item.content" class="log-content">
                                        {{ item.content }}
                                    </div>
                                </div>
                            </List.Item>
                        </template>
                    </List>
                    <Typography.Paragraph v-else type="secondary">
                        No events yet. Start the agent to see execution logs.
                    </Typography.Paragraph>
                </div>
            </Spin>
        </Card>
    </div>
</template>

<style scoped>
.page {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1rem;
}

.panel {
    background: #ffffff;
    border: 1px solid #dbe3ec;
    color: #1f2937;
}

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.section-title {
    margin-top: 2rem !important;
    margin-bottom: 1rem !important;
}

.connection-status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 1rem 0;
    padding: 0.5rem;
    background: #f8fafc;
    border-radius: 4px;
}

.execution-controls {
    background: #f8fafc;
    padding: 1rem;
    border-radius: 4px;
    margin: 1rem 0;
}

.log-container {
    background: #f8fafc;
    border-radius: 4px;
    max-height: 500px;
    overflow-y: auto;
}

.log-item {
    border-bottom: 1px solid #dbe3ec !important;
    padding: 0.75rem !important;
}

.log-entry {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: 100%;
}

.log-type {
    width: fit-content;
}

.log-time {
    font-size: 0.75rem;
    color: #6b7280;
}

.log-message {
    color: #1f2937;
    font-size: 0.9rem;
}

.log-content {
    background: #ffffff;
    padding: 0.5rem;
    border-radius: 3px;
    overflow-x: auto;
}

.log-content pre {
    margin: 0;
    font-size: 0.8rem;
    color: #4b5563;
}

.response-section {
    margin-top: 2rem;
}

.response-card {
    background: #ffffff;
    border: 1px solid #dbe3ec;
}

.response-final {
    border-color: #2563eb;
    box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.25);
}

.response-content {
    color: #1f2937;
    font-size: 1rem;
    line-height: 1.6;
    white-space: pre-wrap;
    word-wrap: break-word;
    padding: 0.5rem;
}

.markdown-body :deep(h1),
.markdown-body :deep(h2),
.markdown-body :deep(h3) {
    color: #1f2937;
    margin-top: 1rem;
    margin-bottom: 0.5rem;
}

.markdown-body :deep(ul),
.markdown-body :deep(ol) {
    padding-left: 1.5rem;
    margin-bottom: 1rem;
    color: #1f2937;
}

.markdown-body :deep(code) {
    background: #eff6ff;
    padding: 0.2rem 0.4rem;
    border-radius: 4px;
    font-family: monospace;
    color: #1d4ed8;
}

.markdown-body :deep(p) {
    margin-bottom: 1rem;
}
</style>
