<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { Card, Typography, List, Tag, Button, Spin, message } from 'ant-design-vue'
import { apiClient, API } from '../router/api'
import type { Role } from '../types/organization'
import type { ProgressSessionApi, ProgressFlowApi, RoleProgressItem } from '../types/onboarding'

const router = useRouter()
const loading = ref(false)
const rows = ref<RoleProgressItem[]>([])

const websocketUrl = (roleId: string) => {
    const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
    return `${protocol}://${window.location.host}/ws/onboarding/${roleId}/`
}

const runProgressMonitor = (roleId: string): Promise<string> =>
    new Promise((resolve, reject) => {
        const ws = new WebSocket(websocketUrl(roleId))
        const timeout = window.setTimeout(() => {
            ws.close()
            reject(new Error('Progress monitor timed out'))
        }, 30000)

        ws.onopen = () => {
            ws.send(
                JSON.stringify({
                    action: 'progress_monitor',
                    role_uuid: roleId,
                }),
            )
        }

        ws.onmessage = (event) => {
            try {
                const payload = JSON.parse(event.data)
                if (payload.type === 'completed') {
                    window.clearTimeout(timeout)
                    const feedback =
                        payload.content?.feedback || payload.message || 'No feedback returned.'
                    ws.close()
                    resolve(String(feedback))
                } else if (payload.type === 'error') {
                    window.clearTimeout(timeout)
                    ws.close()
                    reject(new Error(payload.message || 'Progress monitor failed'))
                }
            } catch {
                window.clearTimeout(timeout)
                ws.close()
                reject(new Error('Invalid monitor response'))
            }
        }

        ws.onerror = () => {
            window.clearTimeout(timeout)
            ws.close()
            reject(new Error('Progress monitor websocket error'))
        }
    })

const loadProgress = async () => {
    loading.value = true
    try {
        const [rolesRes, sessionsRes, flowsRes] = await Promise.all([
            apiClient.get<Role[]>(API.organization.roles.mine()),
            apiClient.get<ProgressSessionApi[]>(API.onboarding.sessions.list()),
            apiClient.get<ProgressFlowApi[]>(API.onboarding.flows.list()),
        ])

        const roles = Array.isArray(rolesRes.data) ? rolesRes.data : []
        const sessions = Array.isArray(sessionsRes.data) ? sessionsRes.data : []
        const flows = Array.isArray(flowsRes.data) ? flowsRes.data : []

        rows.value = roles.map((role) => {
            const roleSessions = sessions
                .filter((session) => session.role?.uuid === role.uuid)
                .sort(
                    (a, b) =>
                        new Date(b.updated_at || 0).getTime() -
                        new Date(a.updated_at || 0).getTime(),
                )
            const latestSession = roleSessions[0]
            const flow = flows.find((f) => f.role?.uuid === role.uuid)

            return {
                role,
                latestStatus: latestSession?.status || 'not_started',
                latestSessionUuid: latestSession?.uuid,
                flowTitle: flow?.title,
                feedback: undefined,
                loadingFeedback: true,
            }
        })

        for (const row of rows.value) {
            try {
                row.feedback = await runProgressMonitor(row.role.uuid)
            } catch (error) {
                row.feedback =
                    error instanceof Error ? error.message : 'Unable to fetch monitor feedback.'
            } finally {
                row.loadingFeedback = false
            }
        }
    } catch {
        message.error('Failed to load progress overview')
    } finally {
        loading.value = false
    }
}

onMounted(() => {
    loadProgress()
})
</script>

<template>
    <div class="page">
        <Typography.Title :level="2">Onboarding Progress</Typography.Title>
        <Typography.Paragraph type="secondary">
            Review each role's onboarding status and monitor feedback.
        </Typography.Paragraph>

        <Card class="panel" :bordered="false">
            <Spin :spinning="loading" tip="Loading progress...">
                <List :data-source="rows" item-layout="vertical">
                    <template #renderItem="{ item }">
                        <List.Item>
                            <List.Item.Meta
                                :title="item.role.name"
                                :description="item.flowTitle || 'No active flow yet'"
                            />
                            <div class="row-meta">
                                <Tag
                                    :color="
                                        item.latestStatus === 'completed'
                                            ? 'green'
                                            : item.latestStatus === 'active'
                                              ? 'blue'
                                              : 'default'
                                    "
                                >
                                    {{ item.latestStatus }}
                                </Tag>
                                <Button
                                    type="primary"
                                    @click="router.push(`/progress/${item.role.uuid}`)"
                                >
                                    View Details
                                </Button>
                            </div>
                            <div class="feedback-block">
                                <Typography.Text strong>Progress Monitor:</Typography.Text>
                                <Spin
                                    v-if="item.loadingFeedback"
                                    size="small"
                                    style="margin-left: 0.5rem"
                                />
                                <Typography.Paragraph v-else class="feedback-text">
                                    {{ item.feedback || 'No feedback yet.' }}
                                </Typography.Paragraph>
                            </div>
                        </List.Item>
                    </template>
                </List>
            </Spin>
        </Card>
    </div>
</template>

<style scoped>
.page {
    max-width: 960px;
    margin: 0 auto;
    padding: 2rem 1rem;
}
.panel {
    background: #0f172a;
    border: 1px solid #1f2937;
}
.row-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: 0.5rem;
}
.feedback-block {
    margin-top: 0.8rem;
}
.feedback-text {
    margin-top: 0.4rem;
    color: #cbd5e1;
    white-space: pre-wrap;
}
</style>
