import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'
import { BookTemplate, TemplateStructure, TemplateFile, TemplateFolder } from '@/lib/types/database'
export class TemplateService {
private supabase = createClientComponentClient()
async getAvailableTemplates(): Promise<BookTemplate[]> {
const { data, error } = await this.supabase
.from('book_templates')
.select('*')
.eq('is_system', true)
.order('is_default', { ascending: false })
.order('created_at', { ascending: true })
if (error) {
console.error('Error fetching templates:', error)
throw new Error('Failed to fetch templates')
}
return data || []
}
async getTemplateById(id: string): Promise<BookTemplate | null> {
const { data, error } = await this.supabase
.from('book_templates')
.select('*')
.eq('id', id)
.single()
if (error) {
console.error('Error fetching template:', error)
return null
}
return data
}
async getDefaultTemplate(): Promise<BookTemplate | null> {
const { data, error } = await this.supabase
.from('book_templates')
.select('*')
.eq('is_default', true)
.eq('is_system', true)
.single()
if (error) {
console.error('Error fetching default template:', error)
return null
}
return data
}
async createBookFromTemplate(supabase: any, bookId: string, templateId?: string): Promise<void> {
try {
let template: BookTemplate | null = null
if (templateId) {
// Use the server supabase instance for template lookup
const { data, error } = await supabase
.from('book_templates')
.select('*')
.eq('id', templateId)
.single()
if (!error && data) {
template = data
}
}
if (!template) {
// Get default template using server supabase
const { data, error } = await supabase
.from('book_templates')
.select('*')
.eq('is_default', true)
.eq('is_system', true)
.single()
if (!error && data) {
template = data
}
}
if (!template) {
throw new Error('No template found')
}
await this.applyTemplateStructure(supabase, bookId, template.structure)
} catch (error) {
console.error('Error creating book from template:', error)
throw error
}
}
private async applyTemplateStructure(supabase: any, bookId: string, structure: TemplateStructure): Promise<void> {
// Create root level files first
const rootFiles = structure.files.map(file => ({
book_id: bookId,
name: file.name,
type: file.type,
content: file.content,
file_extension: file.file_extension,
mime_type: file.mime_type,
sort_order: file.sort_order,
parent_id: null
}))
// Create root level folders
const rootFolders = structure.folders.map(folder => ({
book_id: bookId,
name: folder.name,
type: folder.type,
expanded: folder.expanded,
sort_order: folder.sort_order,
parent_id: null
}))
// Insert root items
const rootItems = [...rootFiles, ...rootFolders]
const { data: createdRootItems, error: rootError } = await supabase
.from('file_system_items')
.insert(rootItems)
.select()
if (rootError) {
console.error('Error creating root items:', rootError)
throw new Error('Failed to create root structure')
}
// Create nested items for folders with children
for (const folder of structure.folders) {
if (folder.children && folder.children.length > 0) {
const createdFolder = createdRootItems.find((item: any) => item.name === folder.name && item.type === 'folder')
if (createdFolder) {
await this.createFolderChildren(supabase, bookId, createdFolder.id, folder.children)
}
}
}
}
private async createFolderChildren(supabase: any, bookId: string, parentId: string, children: (TemplateFile | TemplateFolder)[]): Promise<void> {
const childItems = children.map(child => ({
book_id: bookId,
parent_id: parentId,
name: child.name,
type: child.type,
sort_order: child.sort_order,
...(child.type === 'file' && {
content: (child as TemplateFile).content,
file_extension: (child as TemplateFile).file_extension,
mime_type: (child as TemplateFile).mime_type
}),
...(child.type === 'folder' && {
expanded: (child as TemplateFolder).expanded
})
}))
const { data: createdItems, error } = await supabase
.from('file_system_items')
.insert(childItems)
.select()
if (error) {
console.error('Error creating child items:', error)
throw new Error('Failed to create folder contents')
}
// Recursively create nested folder children
for (const child of children) {
if (child.type === 'folder' && (child as TemplateFolder).children) {
const createdFolder = createdItems.find((item: any) => item.name === child.name && item.type === 'folder')
if (createdFolder) {
await this.createFolderChildren(supabase, bookId, createdFolder.id, (child as TemplateFolder).children!)
}
}
}
}
}
export const templateService = new TemplateService()