<template>
    <OutlineEditor v-model="chapters" />
    <NLayout class="h-full">
        <NLayoutHeader class="flex items-center px-8" style="height: 64px">
            <span class="text-lg flex-1">论文助手</span>
            <template v-if="isLogin">
                <n-popover placement="bottom" trigger="click">
                    <template #trigger>
                        <n-button text>
                            <user-avatar avatarType="medium" onlyAvatar />
                        </n-button>
                    </template>
                    <n-button size="small" @click="logout" text>退出登录</n-button>
                </n-popover>
            </template>

            <template v-else>
                <n-button round @click="showLogin = true" type="primary" size="small">登录</n-button>
            </template>
        </NLayoutHeader>
        <NLayoutContent position="absolute" style="top: 64px; bottom: 0" class="px-8 py-4">
            <NSpace class="pb-8">
                <NButton type="primary" @click="onCreate">创建</NButton>
            </NSpace>
            <n-data-table
                remote
                :columns="columns"
                :data="tableData"
                :pagination="paginationReactive"
                :bordered="false"
                @update:page="getData"
            />
        </NLayoutContent>
    </NLayout>
    <n-modal v-model:show="showModal">
        <n-card style="width: 800px" title="生成结果" :bordered="false" size="huge" role="dialog" aria-modal="true">
            <n-data-table
                remote
                :columns="resultColumns"
                :data="resultData"
                :pagination="resultsPagination"
                :bordered="false"
                @update:page="getResults"
            />
        </n-card>
    </n-modal>
    <n-modal v-model:show="showForm">
        <n-card
            style="width: 600px"
            :title="orderId ? '编辑' : '创建'"
            :bordered="false"
            size="huge"
            role="dialog"
            aria-modal="true"
        >
            <NForm ref="form" :model="model" :rules="rules">
                <NFormItem label="专业" path="major">
                    <NInput v-model:value="model.major" />
                </NFormItem>
                <NFormItem label="标题" path="title">
                    <NInput v-model:value="model.title" />
                </NFormItem>
                <NFormItem label="描述" path="description">
                    <NInput type="textarea" v-model:value="model.description" />
                </NFormItem>
                <NFormItem label="备注" path="remark">
                    <NInput v-model:value="model.remark" />
                </NFormItem>
            </NForm>
            <NSpace class="text-right" justify="end">
                <NButton @click="() => (showForm = false)">取消</NButton>
                <NButton type="primary" @click="submit" :loading="loading">{{ orderId ? '保存' : '创建' }}</NButton>
            </NSpace>
        </n-card>
    </n-modal>
    <n-modal v-model:show="showLogin" transform-origin="center">
        <n-card class="!max-w-xl !rounded-xl">
            <div class="text-white text-2xl text-center font-bold py-8">登录</div>
            <div class="max-w-sm my-5 mx-auto pb-16">
                <login-form @success="onLogin" theme="dark"></login-form>
            </div>
        </n-card>
    </n-modal>

    <n-drawer v-model:show="showEditor" width="100%" height="100%" placement="bottom" @afterEnter="onEditorShow">
        <n-drawer-content body-content-style="padding:0">
            <div class="h-full">
                <div id="editor"></div>
            </div>
        </n-drawer-content>
    </n-drawer>
</template>
<script lang="ts" setup>
import { h, defineComponent, ref, reactive, onMounted, Ref, computed } from 'vue'
import {
    NButton,
    NDataTable,
    NTag,
    NSpace,
    useMessage,
    type DataTableColumn,
    useDialog,
    NModal,
    NCard,
    NForm,
    FormInst,
    NFormItem,
    NInput,
    NPageHeader,
    NLayout,
    NLayoutHeader,
    NLayoutContent,
    NAvatar,
    NPopover,
    NDropdown,
    NDrawer,
    NDrawerContent
} from 'naive-ui'
import { fetchPaperOrders, fetchGenPaper, fetchPaperResults, fetchCreatePaperOrder, fetchUpdatePaperOrder } from '@/api'
import { format, parseISO } from 'date-fns'
import { UserAvatar } from '@/components/common'
import { LoginForm } from '@/components/common'
import { useUserStore } from '@/store'
import { storeToRefs } from 'pinia'
import MarkdownIt from 'markdown-it'
import mdKatex from '@traptitech/markdown-it-katex'
import mila from 'markdown-it-link-attributes'
import hljs from 'highlight.js'
import { t } from '@/locales'
import Vditor from 'vditor'
import 'vditor/src/assets/less/index.less'
import OutlineEditor from '@/components/common/OutlineEditor.vue'

const message = useMessage()
const showLogin = ref(false)
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const dialog = useDialog()
const isLogin = computed(() => {
    return !!userInfo.value.id
})
onMounted(() => {
    getData()
    if (!isLogin.value) {
        showLogin.value = true
    }
})
function logout() {
    dialog.create({
        title: '提示',
        content: '确认要退出登录吗？',
        positiveText: '退出登录',
        negativeText: '取消',
        maskClosable: false,
        onPositiveClick: () => {
            userStore.logout()
            message.success('退出登录成功')
            tableData.value = []
            resultData.value = []
        }
    })
}
function onLogin() {
    showLogin.value = false
    getData()
}
const tableData = ref([])
function timeFormatter(rowData: any, rowIndex: number) {
    return format(parseISO(rowData.createdAt), 'yyyy-MM-dd HH:mm:ss')
}
const columns: DataTableColumn[] = [
    {
        title: '#',
        key: 'id',
        width: 150
    },
    {
        title: '创建时间',
        key: 'createdAt',
        render: timeFormatter
    },
    {
        title: '标题',
        key: 'title'
    },
    {
        title: '描述',
        key: 'description',
        ellipsis: {
            tooltip: true
        }
    },
    {
        title: '备注',
        key: 'remark'
    },
    {
        title: '状态',
        key: 'length',
        align: 'center',
        render(rowData: any, rowIndex: number) {
            switch (rowData.status) {
                case 'pending':
                    return h(NTag, null, { default: () => '待生成' })
                case 'generating':
                    return h(NTag, { type: 'info' }, { default: () => '生成中' })
                case 'complete':
                    return h(NTag, { type: 'success' }, { default: () => '已生成' })
                default:
                    return '未知'
            }
        }
    },
    {
        title: '操作',
        key: 'actions',
        align: 'center',
        width: '250px',
        render(row: any) {
            return h(NSpace, { justify: 'center' }, () => [
                h(
                    NButton,
                    {
                        type: 'primary',
                        size: 'small',
                        onClick: () => gen(row)
                    },
                    () => '生成'
                ),
                h(
                    NButton,
                    {
                        strong: true,
                        size: 'small',
                        onClick: () => showResults(row)
                    },
                    { default: () => '查看' }
                ),
                h(
                    NButton,
                    {
                        strong: true,
                        tertiary: true,
                        size: 'small',
                        onClick: () => editRow(row)
                    },
                    { default: () => '编辑' }
                )
            ])
        }
    }
]

const paginationReactive = reactive({
    page: 1,
    pageSize: 10,
    showSizePicker: false,
    pageSizes: [10],
    pageCount: 1,
    onChange: (page: number) => {
        paginationReactive.page = page
    },
    onUpdatePageSize: (pageSize: number) => {
        paginationReactive.pageSize = pageSize
        paginationReactive.page = 1
    }
})

async function getData() {
    const res: any = await fetchPaperOrders({
        page: {
            page: paginationReactive.page,
            limit: paginationReactive.pageSize
        },
        search: {
            order: {
                createdAt: 'desc'
            }
        }
    })
    tableData.value = res.items
    paginationReactive.pageCount = res.meta.totalPages
}

async function gen(row: any) {
    const d = dialog.success({
        title: '生成',
        content: '确认开始生成吗？',
        positiveText: '确认',
        negativeText: '取消',
        onPositiveClick: () => {
            d.loading = true
            return fetchGenPaper(row.id)
                .then(() => {
                    message.success('已开始生成')
                    getData()
                })
                .catch((e: any) => {
                    message.error(e.message)
                })
                .finally(() => {
                    d.loading = false
                })
        }
    })
}

const orderId = ref<any>(null)
const showModal = ref(false)
const resultData = ref([])
const resultsPagination = reactive({
    page: 1,
    pageSize: 10,
    showSizePicker: false,
    pageSizes: [10],
    pageCount: 1,
    onChange: (page: number) => {
        resultsPagination.page = page
    },
    onUpdatePageSize: (pageSize: number) => {
        resultsPagination.pageSize = pageSize
        resultsPagination.page = 1
    }
})
async function showResults(row: any) {
    orderId.value = row.id
    showModal.value = true
    resultData.value = []
    getResults()
}
function getResults() {
    fetchPaperResults({
        page: {
            page: resultsPagination.page,
            limit: resultsPagination.pageSize
        },
        search: {
            order: {
                createdAt: 'desc'
            },
            where: {
                orderId: orderId.value
            }
        }
    }).then((res: any) => {
        console.log(res)
        resultData.value = res.items
        resultsPagination.pageCount = res.meta.totalPages
    })
}
const resultColumns: DataTableColumn[] = [
    { title: '#', key: 'id' },
    { title: '生成时间', key: 'createdAt', render: timeFormatter },
    { title: '耗时', key: 'duration', render: (row: any) => `${(row.duration / 60).toFixed(1)}分钟` },
    {
        title: 'Token消耗',
        key: 'tokenUsage',
        width: '250px',
        render: (row: any) =>
            `P:${(row.tokenUsage.promptTokens / 1000).toFixed(1)}K / C:${(
                row.tokenUsage.completionTokens / 1000
            ).toFixed(1)}K / T:${(row.tokenUsage.totalTokens / 1000).toFixed(1)}K`
    },
    {
        title: '操作',
        key: 'action',
        align: 'center',
        width: '150px',
        render(row: any) {
            return h(
                NDropdown,
                {
                    size: 'small',
                    options: [
                        {
                            label: 'Word',
                            key: 'word'
                        },
                        {
                            label: 'Markdown',
                            key: 'markdown'
                        }
                    ],
                    trigger: 'click',
                    onSelect(key: string | number) {
                        console.log(key)
                        if (key === 'word') {
                            window.open(row.fileUrl, '_blank')
                        } else {
                            // Create element with <a> tag
                            const link = document.createElement('a')

                            // Create a blog object with the file content which you want to add to the file
                            const file = new Blob([row.content], { type: 'text/plain' })

                            // Add file content in the object URL
                            link.href = URL.createObjectURL(file)

                            // Add file name
                            link.download = row.fileUrl
                                .split('/')
                                .pop()
                                .replace(/\.docx$/, '.md')

                            // Add click event to <a> tag to save file.
                            link.click()
                            URL.revokeObjectURL(link.href)
                        }
                    }
                },
                () => h(NButton, { size: 'small', type: 'primary' }, { default: () => '下载' })
            )
        }
    }
]

const showForm = ref(false)
const form: Ref<FormInst | null> = ref(null)
const model = ref({
    major: '',
    title: '',
    description: '',
    remark: ''
})
const rules = {
    major: [{ required: true, message: '请输入专业' }],
    title: [{ required: true, message: '请输入标题' }],
    description: [{ required: true, message: '请输入描述' }]
}
const loading = ref(false)
function onCreate() {
    orderId.value = null
    model.value = {
        major: '',
        title: '',
        description: '',
        remark: ''
    }
    form.value?.restoreValidation()
    showForm.value = true
}
async function submit() {
    try {
        await form.value?.validate()
    } catch (e: any) {
        return
    }
    try {
        loading.value = true
        await (orderId.value
            ? fetchUpdatePaperOrder(orderId.value, { ...model.value })
            : fetchCreatePaperOrder({ ...model.value }))
        loading.value = false
        showForm.value = false
        getData()
    } catch (e: any) {
        message.error(e.message)
        loading.value = false
    }
}
function editRow(row: any) {
    model.value = {
        major: row.major,
        title: row.title,
        description: row.description,
        remark: row.remark
    }
    orderId.value = row.id
    form.value?.restoreValidation()
    showForm.value = true
}

const mdi = new MarkdownIt({
    linkify: true,
    highlight(code, language) {
        const validLang = !!(language && hljs.getLanguage(language))
        if (validLang) {
            const lang = language ?? ''
            return highlightBlock(hljs.highlight(code, { language: lang }).value, lang)
        }
        return highlightBlock(hljs.highlightAuto(code).value, '')
    }
})

mdi.use(mila, { attrs: { target: '_blank', rel: 'noopener' } })
mdi.use(mdKatex, { blockClass: 'katexmath-block rounded-md p-[10px]', errorColor: ' #cc0000' })
function highlightBlock(str: string, lang?: string) {
    return `<pre class="code-block-wrapper"><div class="code-block-header"><span class="code-block-header__lang">${lang}</span><span class="code-block-header__copy">${t(
        'chat.copyCode'
    )}</span></div><code class="hljs code-block-body ${lang}">${str}</code></pre>`
}

const showEditor = ref(false)
function onEditorShow() {
    console.log('show')
    const vditor = new Vditor('editor', {
        height: '100%'
    })
}

const chapters: Ref<any[]> = ref([
    { children: [], title: 'asdf' },
    { children: [], title: 'asdf' },
    {
        children: [
            { children: [], title: 'werwefwsdfasdf' },
            {
                children: [
                    { children: [], title: 'sdf' },
                    { children: [], title: '' }
                ],
                title: 'asdf'
            }
        ],
        title: 'asdf'
    }
])
</script>
