import { MongoClient } from 'mongodb';
import { execSync } from 'child_process';
import crypto from 'crypto';
import fs from 'fs';

const MONGO_URI = "mongodb+srv://admtracksteel:mongodb26@cluster0.a4xiilu.mongodb.net/ts_gpi";
const DB_NAME = "ts_gpi";
const DEFAULT_ORG_ID = "e47e6210-4879-4e5b-bf21-9285d2713123";

const client = new MongoClient(MONGO_URI);

const idMap = new Map();

function getUUID(mongoId) {
    if (!mongoId) return null;
    const mid = mongoId.toString();
    if (idMap.has(mid)) return idMap.get(mid);
    const newUuid = crypto.randomUUID();
    idMap.set(mid, newUuid);
    return newUuid;
}

function sqlSafe(val) {
    if (val === null || val === undefined) return 'NULL';
    if (val instanceof Date) return `'${val.toISOString()}'`;
    if (Array.isArray(val)) return `'{"${val.join('","')}"}'`;
    if (typeof val === 'object' && val.toString && !val.getMonth) { // not a date
        const s = val.toString();
        return `'${s.replace(/'/g, "''")}'`;
    }
    if (typeof val === 'string') return `'${val.replace(/'/g, "''")}'`;
    return val;
}

async function run() {
    try {
        await client.connect();
        console.log("🚀 Conectado ao MongoDB Atlas...");
        const db = client.db(DB_NAME);

        let allSQL = [];

        // 1. Geometrias (Geometry Types)
        const geoms = await db.collection('geometrytypes').find().toArray();
        console.log(`📐 Migrando ${geoms.length} tipos de geometria...`);
        for (const g of geoms) {
            allSQL.push(`INSERT INTO gpi.geometry_types (id, organization_id, name, efficiency_loss, updated_at) VALUES (${sqlSafe(getUUID(g._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(g.name)}, ${sqlSafe(g.efficiencyLoss)}, NOW());`);
        }

        // 2. Fichas Técnicas (Technical Data Sheets)
        const tds = await db.collection('technicaldatasheets').find().toArray();
        console.log(`📚 Migrando ${tds.length} fichas técnicas...`);
        for (const t of tds) {
            allSQL.push(`INSERT INTO gpi.technical_data_sheets (id, organization_id, name, manufacturer, manufacturer_code, type, min_stock, typical_application, solids_volume, density, mixing_ratio, yield_theoretical, wft_min, wft_max, dft_min, dft_max, reducer, mixing_ratio_weight, mixing_ratio_volume, dft_reference, yield_factor, dilution, notes, created_at, updated_at) VALUES (${sqlSafe(getUUID(t._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(t.name)}, ${sqlSafe(t.manufacturer)}, ${sqlSafe(t.manufacturerCode)}, ${sqlSafe(t.type)}, ${sqlSafe(t.minStock)}, ${sqlSafe(t.typicalApplication)}, ${sqlSafe(t.solidsVolume)}, ${sqlSafe(t.density)}, ${sqlSafe(t.mixingRatio)}, ${sqlSafe(t.yieldTheoretical)}, ${sqlSafe(t.wftMin)}, ${sqlSafe(t.wftMax)}, ${sqlSafe(t.dftMin)}, ${sqlSafe(t.dftMax)}, ${sqlSafe(t.reducer)}, ${sqlSafe(t.mixingRatioWeight)}, ${sqlSafe(t.mixingRatioVolume)}, ${sqlSafe(t.dftReference)}, ${sqlSafe(t.yieldFactor)}, ${sqlSafe(t.dilution)}, ${sqlSafe(t.notes)}, ${sqlSafe(t.createdAt)}, ${sqlSafe(t.updatedAt)});`);
        }

        // 3. Projetos (Projects)
        const projs = await db.collection('projects').find().toArray();
        console.log(`📦 Migrando ${projs.length} projetos...`);
        for (const p of projs) {
            allSQL.push(`INSERT INTO gpi.projects (id, organization_id, name, client, start_date, end_date, environment, technician, weight_kg, status, created_at, updated_at) VALUES (${sqlSafe(getUUID(p._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(p.name)}, ${sqlSafe(p.client)}, ${sqlSafe(p.startDate)}, ${sqlSafe(p.endDate)}, ${sqlSafe(p.environment)}, ${sqlSafe(p.technician)}, ${sqlSafe(p.weightKg)}, 'active', ${sqlSafe(p.createdAt)}, ${sqlSafe(p.updatedAt)});`);
        }

        // 4. Esquemas de Pintura (Painting Schemes)
        const schemes = await db.collection('paintingschemes').find().toArray();
        console.log(`🎨 Migrando ${schemes.length} esquemas de pintura...`);
        for (const s of schemes) {
            allSQL.push(`INSERT INTO gpi.painting_schemes (id, organization_id, project_id, name, type, coat, solids_volume, yield_theoretical, eps_min, eps_max, dilution, manufacturer, color, paint_consumption, thinner_consumption, paint_id, thinner_id, color_hex, thinner_symbol, notes, created_at, updated_at) VALUES (${sqlSafe(crypto.randomUUID())}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(getUUID(s.projectId))}, ${sqlSafe(s.name)}, ${sqlSafe(s.type)}, ${sqlSafe(s.coat)}, ${sqlSafe(s.solidsVolume)}, ${sqlSafe(s.yieldTheoretical)}, ${sqlSafe(s.epsMin)}, ${sqlSafe(s.epsMax)}, ${sqlSafe(s.dilution)}, ${sqlSafe(s.manufacturer)}, ${sqlSafe(s.color)}, ${sqlSafe(s.paintConsumption)}, ${sqlSafe(s.thinnerConsumption)}, ${sqlSafe(s.paintId)}, ${sqlSafe(s.thinnerId)}, ${sqlSafe(s.colorHex)}, ${sqlSafe(s.thinnerSymbol)}, ${sqlSafe(s.notes)}, NOW(), NOW());`);
        }

        // 5. Peças (Parts)
        const parts = await db.collection('parts').find().toArray();
        console.log(`🧩 Migrando ${parts.length} peças...`);
        for (const pt of parts) {
            allSQL.push(`INSERT INTO gpi.parts (id, organization_id, project_id, description, dimensions, weight, type, area, quantity, notes, created_at, updated_at) VALUES (${sqlSafe(getUUID(pt._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(getUUID(pt.projectId))}, ${sqlSafe(pt.description)}, ${sqlSafe(pt.dimensions)}, ${sqlSafe(pt.weight)}, ${sqlSafe(pt.type)}, ${sqlSafe(pt.area)}, ${sqlSafe(pt.quantity)}, ${sqlSafe(pt.notes)}, NOW(), NOW());`);
        }

        // 6. Itens de Estoque (Stock Items)
        const stockItems = await db.collection('stockitems').find().toArray();
        console.log(`🏭 Migrando ${stockItems.length} itens de estoque...`);
        for (const item of stockItems) {
            allSQL.push(`INSERT INTO gpi.stock_items (id, organization_id, name, type, batch_number, quantity, unit, data_sheet_id, location, expiration_date, status, notes, created_at, updated_at) VALUES (${sqlSafe(getUUID(item._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(item.name)}, ${sqlSafe(item.type)}, ${sqlSafe(item.batchNumber)}, ${sqlSafe(item.quantity)}, ${sqlSafe(item.unit)}, ${sqlSafe(item.dataSheetId)}, ${sqlSafe(item.location)}, ${sqlSafe(item.expirationDate)}, ${sqlSafe(item.status)}, ${sqlSafe(item.notes)}, NOW(), NOW());`);
        }

        // 7. Notificações (Notifications)
        const notifs = await db.collection('notifications').find().toArray();
        console.log(`🔔 Migrando ${notifs.length} notificações...`);
        for (const n of notifs) {
            allSQL.push(`INSERT INTO gpi.notifications (id, organization_id, title, message, type, is_read, is_archived, created_at) VALUES (${sqlSafe(getUUID(n._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(n.title)}, ${sqlSafe(n.message)}, ${sqlSafe(n.type)}, ${sqlSafe(n.isRead)}, ${sqlSafe(n.isArchived)}, ${sqlSafe(n.createdAt)});`);
        }

        // 8. Estudos de Rendimento (Yield Studies)
        const yields = await db.collection('yieldstudies').find().toArray();
        console.log(`📈 Migrando ${yields.length} estudos de rendimento...`);
        for (const y of yields) {
            allSQL.push(`INSERT INTO gpi.yield_studies (id, organization_id, name, data_sheet_id, target_dft, dilution_percent, categories, total_weight, estimated_paint_volume, estimated_reducer_volume, estimated_paint_volume_by_area, estimated_reducer_volume_by_area, average_complexity, created_at, updated_at) VALUES (${sqlSafe(getUUID(y._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(y.name)}, ${sqlSafe(y.dataSheetId)}, ${sqlSafe(y.targetDft)}, ${sqlSafe(y.dilutionPercent)}, ${sqlSafe(JSON.stringify(y.categories))}, ${sqlSafe(y.totalWeight)}, ${sqlSafe(y.estimatedPaintVolume)}, ${sqlSafe(y.estimatedReducerVolume)}, ${sqlSafe(y.estimatedPaintVolumeByArea)}, ${sqlSafe(y.estimatedReducerVolumeByArea)}, ${sqlSafe(y.averageComplexity)}, NOW(), NOW());`);
        }

        // 9. Mensagens (Messages)
        const msgs = await db.collection('messages').find().toArray();
        console.log(`💬 Migrando ${msgs.length} mensagens...`);
        for (const m of msgs) {
            allSQL.push(`INSERT INTO gpi.messages (id, organization_id, message, from_user_id, to_user_id, is_read, created_at) VALUES (${sqlSafe(getUUID(m._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(m.content || m.message)}, NULL, NULL, ${sqlSafe(m.isRead)}, ${sqlSafe(m.createdAt)});`);
        }

        // 10. Logs de Auditoria de Estoque
        const auditLogs = await db.collection('stockauditlogs').find().toArray();
        console.log(`📝 Migrando ${auditLogs.length} logs de auditoria...`);
        for (const al of auditLogs) {
            allSQL.push(`INSERT INTO gpi.stock_audit_logs (id, organization_id, stock_item_id, action, quantity_before, quantity_after, performed_by, details, created_at) VALUES (${sqlSafe(getUUID(al._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(al.stockItemId)}, ${sqlSafe(al.action)}, ${sqlSafe(al.quantityBefore)}, ${sqlSafe(al.quantityAfter)}, ${sqlSafe(al.performedBy)}, ${sqlSafe(al.details)}, ${sqlSafe(al.createdAt)});`);
        }

        // 11. Configurações do Sistema
        const settings = await db.collection('systemsettings').find().toArray();
        console.log(`⚙️ Migrando ${settings.length} configurações...`);
        for (const st of settings) {
             const { _id, settingsId, ...rest } = st;
             allSQL.push(`INSERT INTO gpi.system_settings (id, organization_id, key, value, updated_at) VALUES (${sqlSafe(getUUID(_id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(settingsId || 'global')}, ${sqlSafe(JSON.stringify(rest))}, ${sqlSafe(st.updatedAt)});`);
        }

        // 12. Metadados de Arquivos
        const files = await db.collection('storedfiles').find().toArray();
        console.log(`📁 Migrando ${files.length} metadados de arquivos...`);
        for (const f of files) {
            allSQL.push(`INSERT INTO gpi.stored_files (id, organization_id, filename, mime_type, size_bytes, storage_path, metadata, created_at) VALUES (${sqlSafe(getUUID(f._id))}, ${sqlSafe(DEFAULT_ORG_ID)}, ${sqlSafe(f.filename)}, ${sqlSafe(f.mimeType)}, ${sqlSafe(f.size)}, ${sqlSafe(f.path)}, ${sqlSafe(JSON.stringify(f.metadata))}, ${sqlSafe(f.createdAt)});`);
        }

        if (allSQL.length === 0) {
            console.log("⚠️ Nenhum dado novo encontrado.");
            return;
        }

        console.log("💾 Executando SQL em massa no Supabase...");
        fs.writeFileSync('bulk_migration_final.sql', `TRUNCATE gpi.projects, gpi.technical_data_sheets, gpi.painting_schemes, gpi.parts, gpi.stock_items, gpi.notifications, gpi.yield_studies, gpi.geometry_types, gpi.messages, gpi.stock_audit_logs, gpi.system_settings, gpi.stored_files CASCADE;\n` + allSQL.join('\n'));
        
        execSync(`export PGPASSWORD=Xz0oyb6ArGYG5uAVTVwcvJxRrMuT7EIJ && docker exec -i supabase-db-h0oggskgs0ws0sco8kc4s8ws psql -U supabase_admin -d postgres < bulk_migration_final.sql`);

        console.log("✅ Migração final concluída com sucesso!");

    } catch (e) {
        console.error("❌ ERRO DURANTE MIGRAÇÃO:", e.message);
    } finally {
        await client.close();
    }
}

run();
