import { defineStore } from 'pinia'
import { ref, watch } from 'vue'

const STORAGE_KEY = 'llm-in-text-templates'
const STORAGE_VERSION = 1

const PRESET_TEMPLATES = [
    {
        id: 'preset-meeting-notes',
        name: '会议纪要',
        content: `# 会议纪要

- 日期：
- 时间：
- 地点：
- 参会人：

## 议题

## 讨论记录

## 决议

## 待办事项
- [ ] `,
    },
    {
        id: 'preset-article-outline',
        name: '文章大纲',
        content: `# 标题

> 一句话摘要

## 背景

## 结构

## 关键点

## 结论`,
    },
    {
        id: 'preset-project-plan',
        name: '项目计划',
        content: `# 项目计划

## 目标

## 范围

## 里程碑

## 风险

## 负责人`,
    },
    {
        id: 'preset-research-notes',
        name: '研究笔记',
        content: `# 研究笔记

## 问题定义

## 资料来源

## 观察

## 结论

## 下一步`,
    },
]

const normalizeTemplateName = (value) => String(value ?? '').replace(/\s+/g, ' ').trim()

const normalizeTemplateContent = (value) => String(value ?? '').replace(/\r\n?/g, '\n').replace(/\s+$/, '')

const makeTemplateId = () => {
    if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
        return `custom-${crypto.randomUUID()}`
    }

    return `custom-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`
}

const normalizeStoredTemplate = (template) => {
    if (!template || typeof template !== 'object') return null

    const name = normalizeTemplateName(template.name)
    const content = normalizeTemplateContent(template.content)
    if (!name || !content.trim()) return null

    const createdAt = typeof template.createdAt === 'string' && template.createdAt ? template.createdAt : new Date().toISOString()
    const updatedAt = typeof template.updatedAt === 'string' && template.updatedAt ? template.updatedAt : createdAt

    return {
        id: typeof template.id === 'string' && template.id ? template.id : makeTemplateId(),
        name,
        content,
        createdAt,
        updatedAt,
    }
}

export const useTemplatesStore = defineStore('templates', () => {
    const customTemplates = ref([])
    let isHydrated = false

    const loadTemplates = () => {
        try {
            const stored = localStorage.getItem(STORAGE_KEY)
            if (!stored) return

            const parsed = JSON.parse(stored)
            const rawTemplates = Array.isArray(parsed)
                ? parsed
                : Array.isArray(parsed?.customTemplates)
                    ? parsed.customTemplates
                    : Array.isArray(parsed?.data)
                        ? parsed.data
                        : []

            customTemplates.value = rawTemplates
                .map(normalizeStoredTemplate)
                .filter(Boolean)
        } catch {
            customTemplates.value = []
        }
    }

    const saveTemplates = () => {
        if (!isHydrated) return

        try {
            localStorage.setItem(
                STORAGE_KEY,
                JSON.stringify({
                    version: STORAGE_VERSION,
                    customTemplates: customTemplates.value,
                })
            )
        } catch {
            // Ignore persistence failures in browser storage
        }
    }

    const isCustomTemplateNameTaken = (name, ignoreId = '') => {
        const normalizedName = normalizeTemplateName(name)
        if (!normalizedName) return false

        return customTemplates.value.some((template) => {
            if (ignoreId && template.id === ignoreId) return false
            return template.name.toLowerCase() === normalizedName.toLowerCase()
        })
    }

    const buildUniqueCustomTemplateName = (baseName, ignoreId = '') => {
        const normalizedBaseName = normalizeTemplateName(baseName) || 'Untitled Template'
        let candidate = normalizedBaseName
        let suffix = 2

        while (isCustomTemplateNameTaken(candidate, ignoreId)) {
            candidate = `${normalizedBaseName} ${suffix}`
            suffix += 1
        }

        return candidate
    }

    const createCustomTemplate = ({ name, content }) => {
        const nextName = normalizeTemplateName(name)
        const nextContent = normalizeTemplateContent(content)

        if (!nextName || !nextContent.trim()) {
            return { ok: false, error: 'invalid' }
        }

        if (isCustomTemplateNameTaken(nextName)) {
            return { ok: false, error: 'duplicate' }
        }

        const now = new Date().toISOString()
        const template = {
            id: makeTemplateId(),
            name: nextName,
            content: nextContent,
            createdAt: now,
            updatedAt: now,
        }

        customTemplates.value = [...customTemplates.value, template]
        return { ok: true, template }
    }

    const updateCustomTemplate = (id, { name, content }) => {
        const index = customTemplates.value.findIndex((template) => template.id === id)
        if (index === -1) {
            return { ok: false, error: 'not_found' }
        }

        const nextName = normalizeTemplateName(name)
        const nextContent = normalizeTemplateContent(content)

        if (!nextName || !nextContent.trim()) {
            return { ok: false, error: 'invalid' }
        }

        if (isCustomTemplateNameTaken(nextName, id)) {
            return { ok: false, error: 'duplicate' }
        }

        const now = new Date().toISOString()
        const nextTemplates = [...customTemplates.value]
        nextTemplates[index] = {
            ...nextTemplates[index],
            name: nextName,
            content: nextContent,
            updatedAt: now,
        }

        customTemplates.value = nextTemplates
        return { ok: true, template: nextTemplates[index] }
    }

    const deleteCustomTemplate = (id) => {
        const nextTemplates = customTemplates.value.filter((template) => template.id !== id)
        if (nextTemplates.length === customTemplates.value.length) {
            return false
        }

        customTemplates.value = nextTemplates
        return true
    }

    const getTemplateById = (id) => {
        if (!id) return null

        return PRESET_TEMPLATES.find((template) => template.id === id)
            || customTemplates.value.find((template) => template.id === id)
            || null
    }

    watch(customTemplates, saveTemplates, { deep: true })

    loadTemplates()
    isHydrated = true
    saveTemplates()

    return {
        presetTemplates: PRESET_TEMPLATES,
        customTemplates,
        createCustomTemplate,
        updateCustomTemplate,
        deleteCustomTemplate,
        getTemplateById,
        buildUniqueCustomTemplateName,
        isCustomTemplateNameTaken,
    }
})