import 'dotenv/config';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import db from '../src/database/models/index.js';
import { syncLocationManagers, syncRegionManager, syncZoneManager } from '../src/modules/master/syncHierarchy.service.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

async function run() {
    console.log('--- Seeding Real Geo Data (District -> Area Hierarchy) ---');
    try {
        await db.sequelize.authenticate();
        
        // Read the source seeder file
        const seederPath = path.join(__dirname, '../seeders/20240127-seed-geo-data.js');
        const content = fs.readFileSync(seederPath, 'utf8');

        // Extract arrays using regex
        const zonesMatch = content.match(/const ZONES_DATA = \[([\s\S]*?)\];/);
        const statesMatch = content.match(/const STATES_DATA = \[([\s\S]*?)\];/);
        const citiesMatch = content.match(/const CITIES_DATA = \[([\s\S]*?)\];/);

        if (!zonesMatch || !statesMatch || !citiesMatch) {
            throw new Error('Could not parse geo data arrays from seeder file!');
        }

        // Eval helper (data is trusted since it's our own seeder)
        const ZONES_DATA = eval(`[${zonesMatch[1]}]`);
        const STATES_DATA = eval(`[${statesMatch[1]}]`);
        const CITIES_DATA = eval(`[${citiesMatch[1]}]`);

        console.log(`Extracted ${ZONES_DATA.length} Zones, ${STATES_DATA.length} States, and ${CITIES_DATA.length} Cities.`);

        const { Zone, State, District, Location, Opportunity } = db;
        
        // 1. Seed Zones
        const zoneIdMap = new Map(); // Name -> UUID
        for (const z of ZONES_DATA) {
            const [zoneRecord] = await Zone.findOrCreate({
                where: { name: z.name },
                defaults: { name: z.name, code: z.code }
            });
            zoneIdMap.set(z.name, zoneRecord.id);
        }
        console.log('Zones seeded.');

        // 2. Seed States and link to Zones
        const stateIdMap = new Map(); // Legacy ID -> { id, zoneId }
        for (const s of STATES_DATA) {
            const parentZoneData = ZONES_DATA.find((z: any) => z.states.includes(s.name));
            const zoneId = parentZoneData ? zoneIdMap.get(parentZoneData.name) : null;

            const [stateRecord] = await State.findOrCreate({
                where: { name: s.name },
                defaults: { name: s.name, zoneId: zoneId }
            });
            
            stateIdMap.set(s.id, { id: stateRecord.id, zoneId: zoneId });
        }
        console.log('States seeded.');

        // 3. Seed Districts and Areas (Locations)
        let districtCount = 0;
        let areaCount = 0;
        let opportunityCount = 0;

        for (const c of CITIES_DATA) {
            const parentStateData = stateIdMap.get(c.state_id);
            if (parentStateData) {
                // a. Create District (Primary territory entity)
                const [districtRecord] = await District.findOrCreate({
                    where: { name: c.name, stateId: parentStateData.id },
                    defaults: { 
                        name: c.name, 
                        stateId: parentStateData.id, 
                        zoneId: parentStateData.zoneId 
                    }
                });
                districtCount++;

                // b. Create Area (Granular Location record)
                const [areaRecord] = await Location.findOrCreate({
                    where: { name: c.name, districtId: districtRecord.id },
                    defaults: {
                        name: c.name,
                        city: c.name,
                        districtId: districtRecord.id,
                        isActive: true
                    }
                });
                areaCount++;

                // c. Create associated Opportunity
                const [oppRecord, created] = await Opportunity.findOrCreate({
                    where: { areaId: areaRecord.id },
                    defaults: {
                        districtId: districtRecord.id,
                        areaId: areaRecord.id, // Linking to Area!
                        city: c.name,
                        status: 'inactive',
                        opportunityType: 'New Dealership',
                        capacity: 'Standard',
                        priority: 'Medium',
                        notes: 'Automatically generated from district seed'
                    }
                });
                if (created) opportunityCount++;
            }
        }
        console.log(`✅ Seeded ${districtCount} Districts, ${areaCount} Areas, and ${opportunityCount} Opportunities.`);

        console.log('--- Triggering Hierarchy Synchronization ---');
        const districts = await District.findAll({ attributes: ['id'] });
        for (const d of districts) await syncLocationManagers(d.id);
        
        const regions = await db.Region.findAll({ attributes: ['id'] });
        for (const r of regions) await syncRegionManager(r.id);

        const zonesArr = await Zone.findAll({ attributes: ['id'] });
        for (const z of zonesArr) await syncZoneManager(z.id);

        console.log('--- Synchronization Complete ---');
        process.exit(0);

    } catch (e: any) {
        console.error('❌ Failed:', e.message);
        process.exit(1);
    }
}

run();
