import { getDB } from './database'; export function saveTemplateToDB(template: any) { const db = getDB(); const tx = db.transaction(() => { // 1. Save Project db.prepare(` INSERT OR REPLACE INTO projects (id, brand_id, name, is_template, format, duration) VALUES (?, ?, ?, ?, ?, ?) `).run( template.id, template.brandId || null, template.name || template.id, 1, template.format || 'video', template.duration || 0 ); // 2. Save Layers if (template.layers && Array.isArray(template.layers)) { const insertLayer = db.prepare(` INSERT OR REPLACE INTO timeline_layers (id, project_id, name, type, is_visible, is_locked, is_muted, opacity, volume) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) `); for (const layer of template.layers) { insertLayer.run( layer.id, template.id, layer.name, layer.type || 'visual', layer.isVisible === false ? 0 : 1, layer.isLocked ? 1 : 0, layer.isMuted ? 1 : 0, layer.opacity ?? 1, layer.volume ?? 1 ); } } // 3. Save Elements if (template.elements && Array.isArray(template.elements)) { const insertElement = db.prepare(` INSERT OR REPLACE INTO timeline_elements ( id, layer_id, type, content, start_frame, end_frame, x, y, w, h, scale, rotation, opacity, color, font_family, font_size, text_align, filter, chroma_key_enabled, chroma_key_color ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `); for (const el of template.elements) { insertElement.run( el.id, el.layerId, el.type, el.content || '', el.startFrame || 0, el.endFrame || 0, el.x || 0, el.y || 0, el.w || null, el.h || null, el.scale ?? 1, el.rotation ?? 0, el.opacity ?? 1, el.color || null, el.fontFamily || null, el.fontSize || null, el.textAlign || null, el.filter || null, el.chromaKeyEnabled ? 1 : 0, el.chromaKeyColor || null ); } } }); tx(); } export function getTemplatesFromDB() { const db = getDB(); const projects = db.prepare('SELECT * FROM projects WHERE is_template = 1').all() as any[]; return projects.map(p => { const layers = db.prepare('SELECT * FROM timeline_layers WHERE project_id = ?').all(p.id) as any[]; const elements = db.prepare(` SELECT e.* FROM timeline_elements e JOIN timeline_layers l ON l.id = e.layer_id WHERE l.project_id = ? `).all(p.id) as any[]; // Map DB rows back to application models const mappedLayers = layers.map(l => ({ id: l.id, name: l.name, type: l.type, isVisible: Boolean(l.is_visible), isLocked: Boolean(l.is_locked), isMuted: Boolean(l.is_muted), opacity: l.opacity, volume: l.volume })); const mappedElements = elements.map(e => ({ id: e.id, layerId: e.layer_id, type: e.type, content: e.content, startFrame: e.start_frame, endFrame: e.end_frame, x: e.x, y: e.y, w: e.w, h: e.h, scale: e.scale, rotation: e.rotation, opacity: e.opacity, color: e.color, fontFamily: e.font_family, fontSize: e.font_size, textAlign: e.text_align, filter: e.filter, chromaKeyEnabled: Boolean(e.chroma_key_enabled), chromaKeyColor: e.chroma_key_color })); return { id: p.id, brandId: p.brand_id, name: p.name, format: p.format, duration: p.duration, layers: mappedLayers, elements: mappedElements }; }); } export function deleteTemplateFromDB(templateId: string) { const db = getDB(); db.prepare('DELETE FROM projects WHERE id = ?').run(templateId); return true; } // ═══ Brand DAOs ═══ export function saveBrandToDB(brand: any) { const db = getDB(); const tx = db.transaction(() => { db.prepare('INSERT OR REPLACE INTO brands (id, name, tagline, industry) VALUES (?, ?, ?, ?)').run( brand.id, brand.name || brand.id, brand.tagline || '', brand.industry || '' ); if (brand.design) { const d = brand.design; db.prepare(` INSERT OR REPLACE INTO brand_design ( brand_id, primary_color, secondary_color, text_color, base_font, logo_url, frame_thickness, title_font, title_size, title_color, subtitle_font, subtitle_size, subtitle_color, paragraph_font, paragraph_size, paragraph_color ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `).run( brand.id, d.primaryColor || '#000000', d.secondaryColor || '#FFFFFF', d.textColor || '#FFFFFF', d.baseFont || 'Inter', d.logoUrl || '', d.frameThickness || 0, d.titleFont || '', d.titleSize || null, d.titleColor || '', d.subtitleFont || '', d.subtitleSize || null, d.subtitleColor || '', d.paragraphFont || '', d.paragraphSize || null, d.paragraphColor || '' ); } }); tx(); return true; } export function getBrandsFromDB() { const db = getDB(); const brands = db.prepare('SELECT * FROM brands').all() as any[]; return brands.map(b => { const design = db.prepare('SELECT * FROM brand_design WHERE brand_id = ?').get(b.id) as any; const mappedDesign = design ? { primaryColor: design.primary_color, secondaryColor: design.secondary_color, textColor: design.text_color, baseFont: design.base_font, logoUrl: design.logo_url, frameThickness: design.frame_thickness, titleFont: design.title_font, titleSize: design.title_size, titleColor: design.title_color, subtitleFont: design.subtitle_font, subtitleSize: design.subtitle_size, subtitleColor: design.subtitle_color, paragraphFont: design.paragraph_font, paragraphSize: design.paragraph_size, paragraphColor: design.paragraph_color, brandAssets: [] } : {}; const assets = db.prepare("SELECT * FROM brand_assets WHERE brand_id = ? AND source = 'uploaded'").all(b.id) as any[]; if (mappedDesign) { mappedDesign.brandAssets = assets.map(a => ({ id: a.id, type: a.type, url: a.url, path: a.path })); } return { id: b.id, name: b.name, tagline: b.tagline, industry: b.industry, design: mappedDesign }; }); } export function deleteBrandFromDB(brandId: string) { const db = getDB(); db.prepare('DELETE FROM brands WHERE id = ?').run(brandId); return true; } // ═══ Generated Media DAOs ═══ export function registerGeneratedMediaDB(brandId: string, type: 'video' | 'image', filePath: string) { const db = getDB(); db.prepare(` INSERT OR IGNORE INTO brand_assets (id, brand_id, type, source, path, name) VALUES (?, ?, ?, ?, ?, ?) `).run(filePath, brandId, type, 'generated', filePath, filePath); return true; } export function renameGeneratedMediaDB(brandId: string, type: 'video' | 'image', filePath: string, newName: string) { const db = getDB(); db.prepare('UPDATE brand_assets SET name = ? WHERE path = ? AND brand_id = ? AND source = ?').run(newName, filePath, brandId, 'generated'); return true; } export function getGeneratedMediaDB(brandId: string, type: 'video' | 'image') { const db = getDB(); const media = db.prepare('SELECT * FROM brand_assets WHERE brand_id = ? AND type = ? AND source = ?').all(brandId, type, 'generated') as any[]; return media.map(m => ({ path: m.path, name: m.name, date: m.created_at })); } // ═══ Content Mesh DAOs ═══ export function saveContentMeshDB(data: any) { const db = getDB(); db.prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)').run('content_mesh', JSON.stringify(data)); return true; } export function getContentMeshDB() { const db = getDB(); const record = db.prepare('SELECT value FROM settings WHERE key = ?').get('content_mesh') as any; if (record) return JSON.parse(record.value); return {}; }