import mysql from 'mysql2/promise';
import bcrypt from 'bcryptjs';

const config = {
	host: process.env.MYSQL_HOST ?? 'localhost',
	port: Number(process.env.MYSQL_PORT ?? 3306),
	user: process.env.MYSQL_USER ?? 'root',
	password: process.env.MYSQL_PASSWORD ?? '',
	database: process.env.MYSQL_DATABASE ?? 'catatanwarung'
};

const SEED_COUNT = Number(process.argv[2] ?? process.env.SEED_COUNT ?? 100);
const SEED_BATCH = process.argv[3] ?? process.env.SEED_BATCH ?? 'seed';
const SEED_PASSWORD = 'member123';
const EMAIL_PREFIX = `warung-${SEED_BATCH}`;

const KATEGORI = ['jajanan', 'makanan', 'minuman', 'sembako', 'kelontong', 'campuran'];

const NAMA_PREFIX = [
	'Warung', 'Toko', 'Kedai', 'Depot', 'Rumah Makan', 'Warkop', 'Kios',
	'Buah Segar', 'Lapak', 'Warung Madura', 'Warung Padang', 'Angkringan'
];

const NAMA_SUFFIX = [
	'Makmur', 'Sejahtera', 'Berkah', 'Jaya', 'Abadi', 'Rezeki', 'Barokah',
	'Sentosa', 'Mulia', 'Asri', 'Nusantara', 'Rakyat', 'Pak Haji', 'Bu Siti',
	'Pak Budi', 'Mbak Dewi', 'Kang Ujang', 'Teh Manis', 'Nasi Uduk', 'Gorengan',
	'Es Campur', 'Sembako Murah', 'Kelontong 24', 'Soto Lamongan', 'Bakso Malang',
	'Mie Ayam', 'Gado-Gado', 'Pecel Lele', 'Martabak', 'Kerupuk', 'Cilok',
	'Kopi Kenangan', 'Warung Tengah Malam', 'Buah Lokal', 'Sayur Segar'
];

/** Perkiraan koordinat pusat provinsi untuk seed tanpa lat/lng di kodepos */
const PROVINSI_COORDS = {
	'ACEH': { lat: 4.6951, lng: 96.7494 },
	'SUMATERA UTARA': { lat: 3.5952, lng: 98.6722 },
	'SUMATERA BARAT': { lat: -0.9471, lng: 100.4172 },
	'RIAU': { lat: 0.5071, lng: 101.4478 },
	'JAMBI': { lat: -1.6101, lng: 103.6131 },
	'SUMATERA SELATAN': { lat: -2.9909, lng: 104.7566 },
	'BENGKULU': { lat: -3.8004, lng: 102.2652 },
	'LAMPUNG': { lat: -5.4294, lng: 105.2621 },
	'KEPULAUAN BANGKA BELITUNG': { lat: -2.7411, lng: 106.4406 },
	'KEPULAUAN RIAU': { lat: 0.9186, lng: 104.4665 },
	'DKI JAKARTA': { lat: -6.2088, lng: 106.8456 },
	'JAWA BARAT': { lat: -6.9175, lng: 107.6191 },
	'JAWA TENGAH': { lat: -7.1509, lng: 110.1403 },
	'DI YOGYAKARTA': { lat: -7.7956, lng: 110.3695 },
	'JAWA TIMUR': { lat: -7.5361, lng: 112.2384 },
	'BANTEN': { lat: -6.4058, lng: 106.064 },
	'BALI': { lat: -8.4095, lng: 115.1889 },
	'NUSA TENGGARA BARAT': { lat: -8.5833, lng: 116.1167 },
	'NUSA TENGGARA TIMUR': { lat: -10.1833, lng: 123.5833 },
	'KALIMANTAN BARAT': { lat: -0.0263, lng: 109.3425 },
	'KALIMANTAN TENGAH': { lat: -2.2107, lng: 113.9108 },
	'KALIMANTAN SELATAN': { lat: -3.3194, lng: 114.5908 },
	'KALIMANTAN TIMUR': { lat: -0.5021, lng: 117.1536 },
	'KALIMANTAN UTARA': { lat: 3.0731, lng: 116.0414 },
	'SULAWESI UTARA': { lat: 1.4748, lng: 124.8421 },
	'SULAWESI TENGAH': { lat: -0.9002, lng: 119.8707 },
	'SULAWESI SELATAN': { lat: -5.1477, lng: 119.4327 },
	'SULAWESI TENGGARA': { lat: -3.9985, lng: 122.513 },
	'GORONTALO': { lat: 0.5435, lng: 123.0585 },
	'SULAWESI BARAT': { lat: -2.8441, lng: 119.2321 },
	'MALUKU': { lat: -3.2385, lng: 130.1453 },
	'MALUKU UTARA': { lat: 0.7826, lng: 127.3618 },
	'PAPUA BARAT': { lat: -1.3361, lng: 133.1747 },
	'PAPUA': { lat: -4.2699, lng: 138.0804 }
};

const FALLBACK_WILAYAH = [
	{ kelurahan: 'GAMBIR', kecamatan: 'GAMBIR', kota: 'JAKARTA PUSAT', provinsi: 'DKI JAKARTA', kode_pos: '10110' },
	{ kelurahan: 'SUKAJADI', kecamatan: 'SUKAJADI', kota: 'KOTA BANDUNG', provinsi: 'JAWA BARAT', kode_pos: '40162' },
	{ kelurahan: 'NGEMPLAK', kecamatan: 'SIMOKERTO', kota: 'KOTA SURABAYA', provinsi: 'JAWA TIMUR', kode_pos: '60181' },
	{ kelurahan: 'BRUMBUNGAN', kecamatan: 'TEGALSARI', kota: 'KOTA SURABAYA', provinsi: 'JAWA TIMUR', kode_pos: '60262' },
	{ kelurahan: 'KOTA BARU', kecamatan: 'PARAKAN', kota: 'KOTA TEGAL', provinsi: 'JAWA TENGAH', kode_pos: '52122' },
	{ kelurahan: 'DENPASAR', kecamatan: 'DENPASAR BARAT', kota: 'KOTA DENPASAR', provinsi: 'BALI', kode_pos: '80111' },
	{ kelurahan: 'MEDAN KOTA', kecamatan: 'MEDAN KOTA', kota: 'KOTA MEDAN', provinsi: 'SUMATERA UTARA', kode_pos: '20211' },
	{ kelurahan: 'PADANG SELATAN', kecamatan: 'PADANG SELATAN', kota: 'KOTA PADANG', provinsi: 'SUMATERA BARAT', kode_pos: '25134' }
];

function slugify(text) {
	return text
		.toLowerCase()
		.trim()
		.replace(/[^\w\s-]/g, '')
		.replace(/[\s_-]+/g, '-')
		.replace(/^-+|-+$/g, '')
		.slice(0, 150);
}

function pad(num, size = 3) {
	return String(num).padStart(size, '0');
}

function pick(list, index) {
	return list[index % list.length];
}

function jitterCoord(base, index, spread = 0.12) {
	const offset = ((index % 19) - 9) * (spread / 9);
	const value = Number.isFinite(base) ? base : 0;
	return Number((value + offset).toFixed(6));
}

function coordsForProvinsi(provinsi, index) {
	const coords = PROVINSI_COORDS[provinsi] ?? PROVINSI_COORDS['DKI JAKARTA'];
	return {
		lat: jitterCoord(coords.lat, index, 0.15),
		lng: jitterCoord(coords.lng, index * 3, 0.15)
	};
}

async function loadWilayahByProvinsi(connection) {
	try {
		const [provinsiRows] = await connection.query(
			`SELECT DISTINCT provinsi FROM tbl_kodepos ORDER BY provinsi ASC`
		);

		if (provinsiRows.length === 0) return null;

		const grouped = new Map();

		for (const row of provinsiRows) {
			const [samples] = await connection.query(
				`SELECT kelurahan, kecamatan, kabupaten AS kota, provinsi, kodepos AS kode_pos
				 FROM tbl_kodepos
				 WHERE provinsi = ?
				 ORDER BY id ASC
				 LIMIT 30`,
				[row.provinsi]
			);
			grouped.set(row.provinsi, samples);
		}

		return grouped;
	} catch {
		return null;
	}
}

function pickWilayah(grouped, index) {
	if (grouped && grouped.size > 0) {
		const provinsiList = [...grouped.keys()];
		const provinsi = provinsiList[index % provinsiList.length];
		const samples = grouped.get(provinsi) ?? [];
		if (samples.length > 0) {
			return samples[index % samples.length];
		}
	}

	return pick(FALLBACK_WILAYAH, index);
}

async function getFreePaketId(connection) {
	const [rows] = await connection.query(
		`SELECT id FROM paket_langganan WHERE kode = 'free' LIMIT 1`
	);
	return rows[0]?.id ?? null;
}

async function seedWarung() {
	const connection = await mysql.createConnection(config);

	try {
		const hashedPassword = await bcrypt.hash(SEED_PASSWORD, 10);
		const wilayahGrouped = await loadWilayahByProvinsi(connection);
		const freePaketId = await getFreePaketId(connection);
		const provinsiCount = wilayahGrouped?.size ?? FALLBACK_WILAYAH.length;

		let inserted = 0;
		let skipped = 0;

		console.log(`Mulai seed ${SEED_COUNT} warung (batch: ${SEED_BATCH})...`);
		console.log(`  → Sumber wilayah: ${wilayahGrouped ? `${provinsiCount} provinsi dari tbl_kodepos` : 'data fallback'}`);

		for (let i = 1; i <= SEED_COUNT; i++) {
			const email = `${EMAIL_PREFIX}-${pad(i)}@catatanwarung.com`;
			const prefix = pick(NAMA_PREFIX, i);
			const suffix = pick(NAMA_SUFFIX, i * 5 + 2);
			const namaWarung = `${prefix} ${suffix} ${pad(i, 4)}`;
			const slug = `${SEED_BATCH}-${pad(i, 4)}-${slugify(namaWarung)}`.slice(0, 170);
			const kategori = pick(KATEGORI, i + Math.floor(i / KATEGORI.length));
			const wilayah = pickWilayah(wilayahGrouped, i * 11);
			const telepon = `08${10 + (i % 9)}${pad(10000000 + i, 8)}`;

			const [existingMember] = await connection.query(
				'SELECT id FROM member WHERE email = ? LIMIT 1',
				[email]
			);
			if (existingMember.length > 0) {
				skipped++;
				continue;
			}

			const [memberResult] = await connection.query(
				`INSERT INTO member (nama, email, password, role, nama_warung, telepon, alamat)
				 VALUES (?, ?, ?, 'member', ?, ?, ?)`,
				[
					`Pemilik ${namaWarung}`,
					email,
					hashedPassword,
					namaWarung,
					telepon,
					`Jl. ${wilayah.kelurahan} No. ${i}`
				]
			);

			const memberId = memberResult.insertId;
			const { lat, lng } = coordsForProvinsi(wilayah.provinsi, i);

			await connection.query(
				`INSERT INTO warung (
					member_id, nama, slug, deskripsi, kategori, alamat,
					kelurahan, kecamatan, kota, provinsi, kode_pos,
					telepon, whatsapp, latitude, longitude,
					jam_buka, jam_tutup, hari_buka, is_aktif, is_publik, mode_inventori
				) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
				[
					memberId,
					namaWarung,
					slug,
					`${namaWarung} — ${kategori} di ${wilayah.kota}, ${wilayah.provinsi}.`,
					kategori,
					`Jl. ${wilayah.kelurahan} No. ${i}, ${wilayah.kecamatan}`,
					wilayah.kelurahan,
					wilayah.kecamatan,
					wilayah.kota,
					wilayah.provinsi,
					wilayah.kode_pos,
					telepon,
					telepon,
					lat,
					lng,
					i % 4 === 0 ? '06:00:00' : '07:30:00',
					i % 5 === 0 ? '22:00:00' : '21:00:00',
					'Senin-Minggu',
					1,
					i % 12 === 0 ? 0 : 1,
					i % 4 === 0 ? 'dengan_stok' : 'tanpa_stok'
				]
			);

			if (freePaketId) {
				await connection.query(
					`INSERT INTO member_langganan (member_id, paket_id, \`interval\`, status, mulai_at, keterangan)
					 VALUES (?, ?, 'bulanan', 'aktif', CURDATE(), ?)`,
					[memberId, freePaketId, `Seed batch ${SEED_BATCH}`]
				);
			}

			inserted++;

			if (inserted % 100 === 0) {
				console.log(`  → ${inserted} warung ditambahkan...`);
			}
		}

		const [countRows] = await connection.query('SELECT COUNT(*) AS total FROM warung');
		const [provinsiDistrib] = await connection.query(
			`SELECT provinsi, COUNT(*) AS jumlah FROM warung GROUP BY provinsi ORDER BY jumlah DESC LIMIT 10`
		);
		const [kategoriDistrib] = await connection.query(
			`SELECT kategori, COUNT(*) AS jumlah FROM warung GROUP BY kategori ORDER BY jumlah DESC`
		);

		console.log(`\nSeed warung selesai.`);
		console.log(`  → Batch          : ${SEED_BATCH}`);
		console.log(`  → Ditambahkan    : ${inserted}`);
		console.log(`  → Dilewati       : ${skipped} (email sudah ada)`);
		console.log(`  → Total warung   : ${countRows[0]?.total ?? 0}`);
		console.log(`  → Login contoh   : ${EMAIL_PREFIX}-0001@catatanwarung.com / ${SEED_PASSWORD}`);
		console.log(`\n  Top provinsi:`);
		for (const row of provinsiDistrib) {
			console.log(`    - ${row.provinsi}: ${row.jumlah}`);
		}
		console.log(`\n  Per kategori:`);
		for (const row of kategoriDistrib) {
			console.log(`    - ${row.kategori}: ${row.jumlah}`);
		}
	} finally {
		await connection.end();
	}
}

seedWarung().catch((error) => {
	console.error('Gagal seed warung:', error.message);
	process.exit(1);
});
