#!/usr/bin/env bun
/**
 * Item Asset Migration Script
 * 
 * Downloads images from existing Discord CDN URLs and saves them locally.
 * Updates database records to use local asset paths.
 * 
 * Usage:
 *   bun run scripts/migrate-item-assets.ts           # Dry run (no changes)
 *   bun run scripts/migrate-item-assets.ts --execute # Actually perform migration
 */

import { resolve, join } from "path";
import { mkdir } from "node:fs/promises";

// Initialize database connection
const { DrizzleClient } = await import("../shared/db/DrizzleClient");
const { items } = await import("../shared/db/schema");

const ASSETS_DIR = resolve(import.meta.dir, "../bot/assets/graphics/items");
const DRY_RUN = !process.argv.includes("--execute");

interface MigrationResult {
    itemId: number;
    itemName: string;
    originalUrl: string;
    newPath: string;
    status: "success" | "skipped" | "failed";
    error?: string;
}

/**
 * Check if a URL is an external URL (not a local asset path)
 */
function isExternalUrl(url: string | null): boolean {
    if (!url) return false;
    return url.startsWith("http://") || url.startsWith("https://");
}

/**
 * Check if a URL is likely a Discord CDN URL
 */
function isDiscordCdnUrl(url: string): boolean {
    return url.includes("cdn.discordapp.com") ||
        url.includes("media.discordapp.net") ||
        url.includes("discord.gg");
}

/**
 * Download an image from a URL and save it locally
 */
async function downloadImage(url: string, destPath: string): Promise<void> {
    const response = await fetch(url);

    if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    const contentType = response.headers.get("content-type") || "";
    if (!contentType.startsWith("image/")) {
        throw new Error(`Invalid content type: ${contentType}`);
    }

    const buffer = await response.arrayBuffer();
    await Bun.write(destPath, buffer);
}

/**
 * Migrate a single item's images
 */
async function migrateItem(item: {
    id: number;
    name: string;
    iconUrl: string | null;
    imageUrl: string | null;
}): Promise<MigrationResult> {
    const result: MigrationResult = {
        itemId: item.id,
        itemName: item.name,
        originalUrl: item.iconUrl || item.imageUrl || "",
        newPath: `/assets/items/${item.id}.png`,
        status: "skipped"
    };

    // Check if either URL needs migration
    const hasExternalIcon = isExternalUrl(item.iconUrl);
    const hasExternalImage = isExternalUrl(item.imageUrl);

    if (!hasExternalIcon && !hasExternalImage) {
        result.status = "skipped";
        return result;
    }

    // Prefer iconUrl, fall back to imageUrl
    const urlToDownload = item.iconUrl || item.imageUrl;

    if (!urlToDownload || !isExternalUrl(urlToDownload)) {
        result.status = "skipped";
        return result;
    }

    result.originalUrl = urlToDownload;
    const destPath = join(ASSETS_DIR, `${item.id}.png`);

    if (DRY_RUN) {
        console.log(`  [DRY RUN] Would download: ${urlToDownload}`);
        console.log(`            -> ${destPath}`);
        result.status = "success";
        return result;
    }

    try {
        // Download the image
        await downloadImage(urlToDownload, destPath);

        // Update database record
        const { eq } = await import("drizzle-orm");
        await DrizzleClient
            .update(items)
            .set({
                iconUrl: `/assets/items/${item.id}.png`,
                imageUrl: `/assets/items/${item.id}.png`,
            })
            .where(eq(items.id, item.id));

        result.status = "success";
        console.log(`  ✅ Migrated: ${item.name} (ID: ${item.id})`);
    } catch (error) {
        result.status = "failed";
        result.error = error instanceof Error ? error.message : String(error);
        console.log(`  ❌ Failed: ${item.name} (ID: ${item.id}) - ${result.error}`);
    }

    return result;
}

/**
 * Main migration function
 */
async function main() {
    console.log("═══════════════════════════════════════════════════════════════");
    console.log("  Item Asset Migration Script");
    console.log("═══════════════════════════════════════════════════════════════");
    console.log();

    if (DRY_RUN) {
        console.log("  ⚠️  DRY RUN MODE - No changes will be made");
        console.log("      Run with --execute to perform actual migration");
        console.log();
    }

    // Ensure assets directory exists
    await mkdir(ASSETS_DIR, { recursive: true });
    console.log(`  📁 Assets directory: ${ASSETS_DIR}`);
    console.log();

    // Fetch all items
    const allItems = await DrizzleClient.select({
        id: items.id,
        name: items.name,
        iconUrl: items.iconUrl,
        imageUrl: items.imageUrl,
    }).from(items);

    console.log(`  📦 Found ${allItems.length} total items`);

    // Filter items that need migration
    const itemsToMigrate = allItems.filter(item =>
        isExternalUrl(item.iconUrl) || isExternalUrl(item.imageUrl)
    );

    console.log(`  🔄 ${itemsToMigrate.length} items have external URLs`);
    console.log();

    if (itemsToMigrate.length === 0) {
        console.log("  ✨ No items need migration!");
        return;
    }

    // Categorize by URL type
    const discordCdnItems = itemsToMigrate.filter(item =>
        isDiscordCdnUrl(item.iconUrl || "") || isDiscordCdnUrl(item.imageUrl || "")
    );
    const otherExternalItems = itemsToMigrate.filter(item =>
        !isDiscordCdnUrl(item.iconUrl || "") && !isDiscordCdnUrl(item.imageUrl || "")
    );

    console.log(`  📊 Breakdown:`);
    console.log(`      - Discord CDN URLs: ${discordCdnItems.length}`);
    console.log(`      - Other external URLs: ${otherExternalItems.length}`);
    console.log();

    // Process migrations
    console.log("  Starting migration...");
    console.log();

    const results: MigrationResult[] = [];

    for (const item of itemsToMigrate) {
        const result = await migrateItem(item);
        results.push(result);
    }

    // Summary
    console.log();
    console.log("═══════════════════════════════════════════════════════════════");
    console.log("  Migration Summary");
    console.log("═══════════════════════════════════════════════════════════════");

    const successful = results.filter(r => r.status === "success").length;
    const skipped = results.filter(r => r.status === "skipped").length;
    const failed = results.filter(r => r.status === "failed").length;

    console.log(`  ✅ Successful: ${successful}`);
    console.log(`  ⏭️  Skipped: ${skipped}`);
    console.log(`  ❌ Failed: ${failed}`);
    console.log();

    if (failed > 0) {
        console.log("  Failed items:");
        for (const result of results.filter(r => r.status === "failed")) {
            console.log(`    - ${result.itemName}: ${result.error}`);
        }
    }

    if (DRY_RUN) {
        console.log();
        console.log("  ⚠️  This was a dry run. Run with --execute to apply changes.");
    }

    // Exit with error code if any failures
    process.exit(failed > 0 ? 1 : 0);
}

// Run
main().catch(error => {
    console.error("Migration failed:", error);
    process.exit(1);
});
