/**
 * merge-locale-duplicates.ts
 *
 * Merges duplicate DE/EN documents into single Payload localized documents.
 *
 * Problem: Before native localization, DE and EN were stored as separate rows.
 * Now each should be one document with locale-specific data in the *_locales tables.
 *
 * Strategy:
 * 1. Products: Match by slug → Keep DE row as canonical, copy EN data, delete EN row
 * 2. Posts: Match by slug → Same strategy
 * 3. Pages: Match by slug map (impressum↔legal-notice, blog↔blog, etc.) → Same strategy
 */

import pg from 'pg';
const { Pool } = pg;

const DB_URL =
    process.env.DATABASE_URI ||
    process.env.POSTGRES_URI ||
    `postgresql://payload:120in09oenaoinsd9iaidon@127.0.0.1:54322/payload`;

const pool = new Pool({ connectionString: DB_URL });

async function q<T = any>(query: string, values: unknown[] = []): Promise<T[]> {
    const result = await pool.query(query, values);
    return result.rows as T[];
}

async function mergeProducts() {
    console.log('\n── PRODUCTS ───────────────────────────────────────');

    const pairs = await q<{ de_id: number; en_id: number; slug: string }>(`
    SELECT 
      de.id as de_id,
      en.id as en_id,
      de_loc.slug as slug
    FROM products de
    JOIN products_locales de_loc ON de_loc._parent_id = de.id AND de_loc._locale = 'de'
    JOIN products_locales en_loc ON en_loc.slug = de_loc.slug AND en_loc._locale = 'en'
    JOIN products en ON en.id = en_loc._parent_id
    WHERE de.id != en.id
  `);

    console.log(`Found ${pairs.length} DE/EN product pairs to merge`);

    for (const { de_id, en_id, slug } of pairs) {
        console.log(`  Merging: ${slug} (DE id=${de_id} ← EN id=${en_id})`);

        const [enData] = await q(`
      SELECT * FROM products_locales WHERE _parent_id = $1 AND _locale = 'en'
    `, [en_id]);

        if (enData) {
            await q(`
        INSERT INTO products_locales (title, description, application, content, _locale, _parent_id)
        VALUES ($1, $2, $3, $4, 'en', $5)
        ON CONFLICT (_locale, _parent_id) DO UPDATE
          SET title = EXCLUDED.title,
              description = EXCLUDED.description,
              application = EXCLUDED.application,
              content = EXCLUDED.content
      `, [enData.title, enData.description, enData.application, enData.content, de_id]);
        }

        // Move categories from EN to DE if DE has none
        await q(`
      UPDATE products_categories SET _parent_id = $1
      WHERE _parent_id = $2
      AND NOT EXISTS (SELECT 1 FROM products_categories WHERE _parent_id = $1)
    `, [de_id, en_id]);

        // Move images (rels) from EN to DE if DE has none
        await q(`
      UPDATE products_rels SET parent = $1
      WHERE parent = $2
      AND NOT EXISTS (SELECT 1 FROM products_rels WHERE parent = $1)
    `, [de_id, en_id]);

        // Copy featuredImage if DE is missing one
        await q(`
      UPDATE products SET featured_image_id = (
        SELECT featured_image_id FROM products WHERE id = $2
      )
      WHERE id = $1 AND featured_image_id IS NULL
    `, [de_id, en_id]);

        // Delete EN locale entry and EN product row
        await q(`DELETE FROM products_locales WHERE _parent_id = $1`, [en_id]);
        await q(`DELETE FROM _products_v WHERE parent = $1`, [en_id]);
        await q(`DELETE FROM products WHERE id = $1`, [en_id]);

        console.log(`  ✓ ${slug}`);
    }

    const [{ count }] = await q(`SELECT count(*) FROM products`);
    console.log(`Products remaining: ${count}`);
}

async function mergePosts() {
    console.log('\n── POSTS ──────────────────────────────────────────');

    const pairs = await q<{ de_id: number; en_id: number; slug: string }>(`
    SELECT 
      de.id as de_id,
      en.id as en_id,
      de_loc.slug as slug
    FROM posts de
    JOIN posts_locales de_loc ON de_loc._parent_id = de.id AND de_loc._locale = 'de'
    JOIN posts_locales en_loc ON en_loc.slug = de_loc.slug AND en_loc._locale = 'en'
    JOIN posts en ON en.id = en_loc._parent_id
    WHERE de.id != en.id
  `);

    console.log(`Found ${pairs.length} DE/EN post pairs to merge`);

    for (const { de_id, en_id, slug } of pairs) {
        console.log(`  Merging post: ${slug} (DE id=${de_id} ← EN id=${en_id})`);

        const [enData] = await q(`
      SELECT * FROM posts_locales WHERE _parent_id = $1 AND _locale = 'en'
    `, [en_id]);

        if (enData) {
            await q(`
        INSERT INTO posts_locales (title, slug, excerpt, category, content, _locale, _parent_id)
        VALUES ($1, $2, $3, $4, $5, 'en', $6)
        ON CONFLICT (_locale, _parent_id) DO UPDATE
          SET title = EXCLUDED.title, slug = EXCLUDED.slug,
              excerpt = EXCLUDED.excerpt, category = EXCLUDED.category,
              content = EXCLUDED.content
      `, [enData.title, enData.slug, enData.excerpt, enData.category, enData.content, de_id]);
        }

        // Copy featuredImage/date from EN if DE is missing
        await q(`
      UPDATE posts SET
        featured_image_id = COALESCE(featured_image_id, (SELECT featured_image_id FROM posts WHERE id = $2)),
        date = COALESCE(date, (SELECT date FROM posts WHERE id = $2))
      WHERE id = $1
    `, [de_id, en_id]);

        await q(`DELETE FROM posts_locales WHERE _parent_id = $1`, [en_id]);
        await q(`DELETE FROM _posts_v WHERE parent = $1`, [en_id]);
        await q(`DELETE FROM posts WHERE id = $1`, [en_id]);

        console.log(`  ✓ ${slug}`);
    }

    const [{ count }] = await q(`SELECT count(*) FROM posts`);
    console.log(`Posts remaining: ${count}`);
}

// DE slug → EN slug mapping for pages
const PAGE_SLUG_MAP: Record<string, string> = {
    impressum: 'legal-notice',
    datenschutz: 'privacy-policy',
    agbs: 'terms',
    kontakt: 'contact',
    produkte: 'products',
    blog: 'blog',
    team: 'team',
    start: 'start',
    danke: 'thanks',
};

async function mergePages() {
    console.log('\n── PAGES ──────────────────────────────────────────');

    for (const [deSlug, enSlug] of Object.entries(PAGE_SLUG_MAP)) {
        const [dePage] = await q<{ id: number }>(`
      SELECT p.id FROM pages p
      JOIN pages_locales pl ON pl._parent_id = p.id AND pl._locale = 'de' AND pl.slug = $1
      LIMIT 1
    `, [deSlug]);

        const [enPage] = await q<{ id: number }>(`
      SELECT p.id FROM pages p
      JOIN pages_locales pl ON pl._parent_id = p.id AND pl._locale = 'en' AND pl.slug = $1
      LIMIT 1
    `, [enSlug]);

        if (!dePage && !enPage) {
            console.log(`  ⚠ No page found for ${deSlug}/${enSlug} — skipping`);
            continue;
        }
        if (!dePage) {
            console.log(`  ⚠ No DE page for "${deSlug}" — EN-only page id=${enPage!.id} kept`);
            continue;
        }
        if (!enPage) {
            console.log(`  ⚠ No EN page for "${enSlug}" — DE-only page id=${dePage.id} kept`);
            continue;
        }
        if (dePage.id === enPage.id) {
            console.log(`  ✓ ${deSlug}/${enSlug} already merged (id=${dePage.id})`);
            continue;
        }

        console.log(`  Merging: ${deSlug}↔${enSlug} (DE id=${dePage.id} ← EN id=${enPage.id})`);

        const [enData] = await q(`
      SELECT * FROM pages_locales WHERE _parent_id = $1 AND _locale = 'en'
    `, [enPage.id]);

        if (enData) {
            await q(`
        INSERT INTO pages_locales (title, slug, excerpt, content, _locale, _parent_id)
        VALUES ($1, $2, $3, $4, 'en', $5)
        ON CONFLICT (_locale, _parent_id) DO UPDATE
          SET title = EXCLUDED.title, slug = EXCLUDED.slug,
              excerpt = EXCLUDED.excerpt, content = EXCLUDED.content
      `, [enData.title, enData.slug, enData.excerpt, enData.content, dePage.id]);
        }

        // Copy featuredImage/layout from EN if DE is missing
        await q(`
      UPDATE pages SET
        featured_image_id = COALESCE(featured_image_id, (SELECT featured_image_id FROM pages WHERE id = $2)),
        layout = COALESCE(layout, (SELECT layout FROM pages WHERE id = $2))
      WHERE id = $1
    `, [dePage.id, enPage.id]);

        await q(`DELETE FROM pages_locales WHERE _parent_id = $1`, [enPage.id]);
        await q(`DELETE FROM _pages_v WHERE parent = $1`, [enPage.id]);
        await q(`DELETE FROM pages WHERE id = $1`, [enPage.id]);

        console.log(`  ✓ ${deSlug}/${enSlug}`);
    }

    const [{ count }] = await q(`SELECT count(*) FROM pages`);
    console.log(`Pages remaining: ${count}`);
}

async function main() {
    console.log('🔀 Merging duplicate locale documents into native Payload localization...');

    try {
        await mergeProducts();
        await mergePosts();
        await mergePages();

        console.log('\n── Final pages state ──────────────────────────────');
        const pages = await q(`
      SELECT p.id, pl._locale, pl.slug, pl.title FROM pages p 
      JOIN pages_locales pl ON pl._parent_id = p.id
      ORDER BY p.id, pl._locale
    `);
        pages.forEach((r) => console.log(`  [id=${r.id}] ${r._locale}: ${r.slug} — ${r.title}`));

        console.log('\n✅ Done!');
    } finally {
        await pool.end();
    }
}

main().catch((err) => {
    console.error('Fatal error:', err);
    process.exit(1);
});
