"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
const typeorm_1 = require("typeorm");
const dotenv = require("dotenv");
const path = require("path");
const fs = require("fs");
const encryption_util_1 = require("../common/utils/encryption.util");
const user_entity_1 = require("./entities/user.entity");
const role_entity_1 = require("./entities/role.entity");
const permission_entity_1 = require("./entities/permission.entity");
const subscription_plan_entity_1 = require("./entities/subscription-plan.entity");
const business_entity_1 = require("./entities/business.entity");
const customer_entity_1 = require("./entities/customer.entity");
const package_entity_1 = require("./entities/package.entity");
const voucher_entity_1 = require("./entities/voucher.entity");
async function seed() {
    const SEED = process.env.SEED;
    if (SEED !== 'true') {
        console.log('SEED env var not set to "true". Skipping seed.');
        process.exit(0);
    }
    const envFile = path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || 'development'}`);
    const defaultEnvFile = path.resolve(process.cwd(), '.env');
    if (fs.existsSync(envFile)) {
        dotenv.config({ path: envFile });
    }
    else if (fs.existsSync(defaultEnvFile)) {
        dotenv.config({ path: defaultEnvFile });
    }
    const ssl = process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false;
    const dataSource = new typeorm_1.DataSource({
        type: (process.env.DB_TYPE || 'mysql'),
        host: process.env.DB_HOST || 'localhost',
        port: parseInt(process.env.DB_PORT || '3306', 10),
        username: process.env.DB_USERNAME || 'root',
        password: process.env.DB_PASSWORD ?? '',
        database: process.env.DB_NAME || 'hbs_db',
        entities: [path.resolve(__dirname, 'entities', '*.entity{.ts,.js}')],
        ssl: ssl,
        logging: false,
    });
    try {
        await dataSource.initialize();
        console.log('Data Source initialized. Starting seed...');
        const roleRepo = dataSource.getRepository(role_entity_1.Role);
        const permissionRepo = dataSource.getRepository(permission_entity_1.Permission);
        const planRepo = dataSource.getRepository(subscription_plan_entity_1.SubscriptionPlan);
        const userRepo = dataSource.getRepository(user_entity_1.User);
        const businessRepo = dataSource.getRepository(business_entity_1.Business);
        const customerRepo = dataSource.getRepository(customer_entity_1.Customer);
        const packageRepo = dataSource.getRepository(package_entity_1.Package);
        const voucherRepo = dataSource.getRepository(voucher_entity_1.Voucher);
        const existingPerms = await permissionRepo.count();
        let permissions = [];
        if (existingPerms === 0) {
            const permDefs = [
                { name: 'users.read', resource: 'users', action: 'read', description: 'View users' },
                { name: 'users.create', resource: 'users', action: 'create', description: 'Create users' },
                { name: 'users.update', resource: 'users', action: 'update', description: 'Update users' },
                { name: 'users.delete', resource: 'users', action: 'delete', description: 'Delete users' },
                { name: 'roles.read', resource: 'roles', action: 'read', description: 'View roles' },
                { name: 'roles.manage', resource: 'roles', action: 'manage', description: 'Manage roles' },
                { name: 'businesses.read', resource: 'businesses', action: 'read', description: 'View businesses' },
                { name: 'businesses.manage', resource: 'businesses', action: 'manage', description: 'Manage businesses' },
                { name: 'subscriptions.read', resource: 'subscriptions', action: 'read', description: 'View subscriptions' },
                { name: 'subscriptions.manage', resource: 'subscriptions', action: 'manage', description: 'Manage subscriptions' },
                { name: 'routers.read', resource: 'routers', action: 'read', description: 'View routers' },
                { name: 'routers.manage', resource: 'routers', action: 'manage', description: 'Manage routers' },
                { name: 'locations.read', resource: 'locations', action: 'read', description: 'View locations' },
                { name: 'locations.manage', resource: 'locations', action: 'manage', description: 'Manage locations' },
                { name: 'packages.read', resource: 'packages', action: 'read', description: 'View packages' },
                { name: 'packages.manage', resource: 'packages', action: 'manage', description: 'Manage packages' },
                { name: 'customers.read', resource: 'customers', action: 'read', description: 'View customers' },
                { name: 'customers.manage', resource: 'customers', action: 'manage', description: 'Manage customers' },
                { name: 'sessions.read', resource: 'sessions', action: 'read', description: 'View sessions' },
                { name: 'sessions.manage', resource: 'sessions', action: 'manage', description: 'Manage sessions' },
                { name: 'vouchers.read', resource: 'vouchers', action: 'read', description: 'View vouchers' },
                { name: 'vouchers.manage', resource: 'vouchers', action: 'manage', description: 'Manage vouchers' },
                { name: 'payments.read', resource: 'payments', action: 'read', description: 'View payments' },
                { name: 'payments.manage', resource: 'payments', action: 'manage', description: 'Manage payments' },
                { name: 'transactions.read', resource: 'transactions', action: 'read', description: 'View transactions' },
                { name: 'transactions.manage', resource: 'transactions', action: 'manage', description: 'Manage transactions' },
                { name: 'invoices.read', resource: 'invoices', action: 'read', description: 'View invoices' },
                { name: 'invoices.manage', resource: 'invoices', action: 'manage', description: 'Manage invoices' },
                { name: 'reports.read', resource: 'reports', action: 'read', description: 'View reports' },
                { name: 'reports.export', resource: 'reports', action: 'export', description: 'Export reports' },
                { name: 'notifications.read', resource: 'notifications', action: 'read', description: 'View notifications' },
                { name: 'notifications.manage', resource: 'notifications', action: 'manage', description: 'Manage notifications' },
                { name: 'tickets.read', resource: 'tickets', action: 'read', description: 'View tickets' },
                { name: 'tickets.manage', resource: 'tickets', action: 'manage', description: 'Manage tickets' },
                { name: 'settings.read', resource: 'settings', action: 'read', description: 'View settings' },
                { name: 'settings.manage', resource: 'settings', action: 'manage', description: 'Manage settings' },
                { name: 'audit.read', resource: 'audit', action: 'read', description: 'View audit logs' },
                { name: 'system.manage', resource: 'system', action: 'manage', description: 'System management' },
                { name: 'mpesa.read', resource: 'mpesa', action: 'read', description: 'View M-Pesa records' },
                { name: 'mpesa.manage', resource: 'mpesa', action: 'manage', description: 'Manage M-Pesa' },
            ];
            permissions = await permissionRepo.save(permDefs.map((p) => permissionRepo.create(p)));
            console.log(`Created ${permissions.length} permissions.`);
        }
        else {
            permissions = await permissionRepo.find();
            console.log('Permissions already exist, skipping.');
        }
        const existingRoles = await roleRepo.count();
        const roles = new Map();
        if (existingRoles === 0) {
            const allPerms = permissions;
            const roleDefs = [
                {
                    name: 'Super Admin',
                    type: role_entity_1.RoleType.SUPER_ADMIN,
                    description: 'Full system access',
                    isSystem: true,
                    permNames: allPerms.map((p) => p.name),
                },
                {
                    name: 'Business Owner',
                    type: role_entity_1.RoleType.BUSINESS_OWNER,
                    description: 'Business owner with full business access',
                    isSystem: true,
                    permNames: allPerms
                        .filter((p) => !['system.manage', 'businesses.manage', 'subscriptions.manage'].includes(p.name))
                        .map((p) => p.name),
                },
                {
                    name: 'Manager',
                    type: role_entity_1.RoleType.MANAGER,
                    description: 'Business manager',
                    isSystem: true,
                    permNames: [
                        'users.read', 'roles.read',
                        'routers.read', 'routers.manage',
                        'locations.read', 'locations.manage',
                        'packages.read', 'packages.manage',
                        'customers.read', 'customers.manage',
                        'sessions.read', 'sessions.manage',
                        'vouchers.read', 'vouchers.manage',
                        'payments.read', 'payments.manage',
                        'transactions.read',
                        'invoices.read', 'invoices.manage',
                        'reports.read', 'reports.export',
                        'notifications.read', 'notifications.manage',
                        'tickets.read', 'tickets.manage',
                        'settings.read', 'settings.manage',
                        'audit.read',
                        'mpesa.read',
                    ],
                },
                {
                    name: 'Accountant',
                    type: role_entity_1.RoleType.ACCOUNTANT,
                    description: 'Financial management',
                    isSystem: true,
                    permNames: [
                        'payments.read', 'payments.manage',
                        'transactions.read', 'transactions.manage',
                        'invoices.read', 'invoices.manage',
                        'reports.read', 'reports.export',
                        'customers.read',
                        'vouchers.read',
                        'mpesa.read',
                        'audit.read',
                    ],
                },
                {
                    name: 'Support Agent',
                    type: role_entity_1.RoleType.SUPPORT_AGENT,
                    description: 'Customer support',
                    isSystem: true,
                    permNames: [
                        'customers.read', 'customers.manage',
                        'sessions.read', 'sessions.manage',
                        'tickets.read', 'tickets.manage',
                        'packages.read',
                        'vouchers.read',
                        'notifications.read',
                        'routers.read',
                    ],
                },
                {
                    name: 'Technician',
                    type: role_entity_1.RoleType.TECHNICIAN,
                    description: 'Technical operations',
                    isSystem: true,
                    permNames: [
                        'routers.read', 'routers.manage',
                        'locations.read',
                        'sessions.read', 'sessions.manage',
                        'packages.read',
                        'customers.read',
                        'notifications.read',
                    ],
                },
                {
                    name: 'Sales Agent',
                    type: role_entity_1.RoleType.SALES_AGENT,
                    description: 'Sales and customer onboarding',
                    isSystem: true,
                    permNames: [
                        'customers.read', 'customers.manage',
                        'vouchers.read', 'vouchers.manage',
                        'packages.read',
                        'payments.read',
                        'sessions.read',
                        'reports.read',
                    ],
                },
                {
                    name: 'Cashier',
                    type: role_entity_1.RoleType.CASHIER,
                    description: 'Point of sale operations',
                    isSystem: true,
                    permNames: [
                        'customers.read',
                        'vouchers.read', 'vouchers.manage',
                        'packages.read',
                        'payments.read', 'payments.manage',
                        'invoices.read',
                        'sessions.read',
                    ],
                },
                {
                    name: 'Customer',
                    type: role_entity_1.RoleType.CUSTOMER,
                    description: 'End customer',
                    isSystem: true,
                    permNames: [
                        'sessions.read',
                        'packages.read',
                        'payments.read',
                        'invoices.read',
                    ],
                },
            ];
            for (const def of roleDefs) {
                const role = roleRepo.create({
                    name: def.name,
                    type: def.type,
                    description: def.description,
                    isSystem: def.isSystem,
                });
                const savedRole = await roleRepo.save(role);
                const rolePermissions = def.permNames
                    .map((name) => allPerms.find((p) => p.name === name))
                    .filter(Boolean);
                savedRole.permissions = rolePermissions;
                await roleRepo.save(savedRole);
                roles.set(def.name, savedRole);
            }
            console.log(`Created ${roles.size} roles.`);
        }
        else {
            const allRoles = await roleRepo.find();
            for (const r of allRoles) {
                roles.set(r.name, r);
            }
            console.log('Roles already exist, skipping.');
        }
        const existingPlans = await planRepo.count();
        if (existingPlans === 0) {
            const plans = [
                planRepo.create({
                    name: 'Free',
                    slug: 'free',
                    description: 'Free tier with basic features',
                    priceKes: 0,
                    billingCycle: subscription_plan_entity_1.BillingCycle.MONTHLY,
                    maxRouters: 1,
                    maxLocations: 1,
                    maxStaff: 2,
                    maxCustomers: 50,
                    includesVouchers: false,
                    includesCustomBranding: false,
                    includesApiAccess: false,
                    includesPrioritySupport: false,
                    includesWhiteLabel: false,
                    commissionRate: 0,
                    isActive: true,
                    sortOrder: 1,
                }),
                planRepo.create({
                    name: 'Pro',
                    slug: 'pro',
                    description: 'Professional tier for growing businesses',
                    priceKes: 2999,
                    billingCycle: subscription_plan_entity_1.BillingCycle.MONTHLY,
                    maxRouters: 10,
                    maxLocations: 5,
                    maxStaff: 50,
                    maxCustomers: 1000,
                    includesVouchers: true,
                    includesCustomBranding: true,
                    includesApiAccess: true,
                    includesPrioritySupport: false,
                    includesWhiteLabel: false,
                    commissionRate: 5,
                    isActive: true,
                    sortOrder: 2,
                }),
                planRepo.create({
                    name: 'Enterprise',
                    slug: 'enterprise',
                    description: 'Enterprise tier with unlimited features',
                    priceKes: 9999,
                    billingCycle: subscription_plan_entity_1.BillingCycle.MONTHLY,
                    maxRouters: 100,
                    maxLocations: 50,
                    maxStaff: 500,
                    maxCustomers: 50000,
                    includesVouchers: true,
                    includesCustomBranding: true,
                    includesApiAccess: true,
                    includesPrioritySupport: true,
                    includesWhiteLabel: true,
                    commissionRate: 10,
                    isActive: true,
                    sortOrder: 3,
                }),
            ];
            await planRepo.save(plans);
            console.log(`Created ${plans.length} subscription plans.`);
        }
        else {
            console.log('Subscription plans already exist, skipping.');
        }
        const existingBusinesses = await businessRepo.count();
        let demoBusinessId = null;
        if (existingBusinesses === 0) {
            const business = businessRepo.create({
                name: 'Demo Hotspot',
                slug: 'demo-hotspot',
                email: 'demo@hotspot.com',
                phone: '+254700000000',
                address: '123 Demo Street',
                city: 'Nairobi',
                country: 'Kenya',
                isActive: true,
            });
            const savedBusiness = await businessRepo.save(business);
            demoBusinessId = savedBusiness.id;
            console.log('Created demo business.');
        }
        else {
            const business = await businessRepo.findOne({ where: { slug: 'demo-hotspot' } });
            if (business) {
                demoBusinessId = business.id;
            }
            console.log('Businesses already exist, skipping.');
        }
        const existingAdmin = await userRepo.findOne({ where: { email: 'admin@hotspot.com' } });
        if (!existingAdmin) {
            const adminRole = roles.get('Super Admin') || (await roleRepo.findOne({ where: { type: role_entity_1.RoleType.SUPER_ADMIN } }));
            const passwordHash = await (0, encryption_util_1.hashPassword)('Admin@123');
            const adminUser = userRepo.create({
                email: 'admin@hotspot.com',
                passwordHash,
                firstName: 'System',
                lastName: 'Admin',
                roleId: adminRole?.id || '',
                isActive: true,
            });
            await userRepo.save(adminUser);
            console.log('Created system admin user (admin@hotspot.com / Admin@123).');
        }
        else {
            console.log('System admin already exists, skipping.');
        }
        const existingDemoOwner = await userRepo.findOne({ where: { email: 'demo@hotspot.com' } });
        if (!existingDemoOwner && demoBusinessId) {
            const ownerRole = roles.get('Business Owner') || (await roleRepo.findOne({ where: { type: role_entity_1.RoleType.BUSINESS_OWNER } }));
            const passwordHash = await (0, encryption_util_1.hashPassword)('Demo@123');
            const demoUser = userRepo.create({
                email: 'demo@hotspot.com',
                passwordHash,
                firstName: 'Demo',
                lastName: 'Owner',
                roleId: ownerRole?.id || '',
                businessId: demoBusinessId,
                isActive: true,
            });
            await userRepo.save(demoUser);
            console.log('Created demo business owner (demo@hotspot.com / Demo@123).');
        }
        else {
            console.log('Demo business owner already exists or no business, skipping.');
        }
        if (demoBusinessId) {
            const existingCustomers = await customerRepo.count({ where: { businessId: demoBusinessId } });
            if (existingCustomers === 0) {
                const customers = [
                    customerRepo.create({ businessId: demoBusinessId, phoneNumber: '+254712000001', firstName: 'Alice', lastName: 'Wanjiku' }),
                    customerRepo.create({ businessId: demoBusinessId, phoneNumber: '+254712000002', firstName: 'Bob', lastName: 'Mwangi' }),
                    customerRepo.create({ businessId: demoBusinessId, phoneNumber: '+254712000003', firstName: 'Carol', lastName: 'Akinyi' }),
                    customerRepo.create({ businessId: demoBusinessId, phoneNumber: '+254712000004', firstName: 'David', lastName: 'Kamau' }),
                    customerRepo.create({ businessId: demoBusinessId, phoneNumber: '+254712000005', firstName: 'Eve', lastName: 'Chebet' }),
                ];
                await customerRepo.save(customers);
                console.log(`Created ${customers.length} demo customers.`);
            }
            else {
                console.log('Demo customers already exist, skipping.');
            }
        }
        if (demoBusinessId) {
            const existingPackages = await packageRepo.count({ where: { businessId: demoBusinessId } });
            if (existingPackages === 0) {
                const packages = [
                    packageRepo.create({ businessId: demoBusinessId, name: '1 Hour', type: package_entity_1.PackageType.TIME, priceKes: 50, durationMinutes: 60, isActive: true, sortOrder: 1 }),
                    packageRepo.create({ businessId: demoBusinessId, name: 'Daily', type: package_entity_1.PackageType.DAILY, priceKes: 150, durationMinutes: 1440, isActive: true, sortOrder: 2 }),
                    packageRepo.create({ businessId: demoBusinessId, name: 'Weekly', type: package_entity_1.PackageType.WEEKLY, priceKes: 500, durationMinutes: 10080, isActive: true, sortOrder: 3 }),
                    packageRepo.create({ businessId: demoBusinessId, name: '1 GB Data', type: package_entity_1.PackageType.DATA, priceKes: 100, dataAllowanceMb: 1024, isActive: true, sortOrder: 4 }),
                    packageRepo.create({ businessId: demoBusinessId, name: '5 GB Data', type: package_entity_1.PackageType.DATA, priceKes: 400, dataAllowanceMb: 5120, isActive: true, sortOrder: 5 }),
                    packageRepo.create({ businessId: demoBusinessId, name: 'Free Trial', type: package_entity_1.PackageType.FREE_TRIAL, priceKes: 0, durationMinutes: 30, dataAllowanceMb: 100, isActive: true, sortOrder: 6 }),
                ];
                const savedPackages = await packageRepo.save(packages);
                console.log(`Created ${savedPackages.length} sample packages.`);
                const existingVouchers = await voucherRepo.count({ where: { businessId: demoBusinessId } });
                if (existingVouchers === 0 && savedPackages.length > 0) {
                    const firstPackage = savedPackages[0];
                    const vouchers = [
                        voucherRepo.create({ businessId: demoBusinessId, code: 'DEMO-FREE-001', packageId: firstPackage.id, status: voucher_entity_1.VoucherStatus.UNUSED }),
                        voucherRepo.create({ businessId: demoBusinessId, code: 'DEMO-FREE-002', packageId: firstPackage.id, status: voucher_entity_1.VoucherStatus.UNUSED }),
                        voucherRepo.create({ businessId: demoBusinessId, code: 'DEMO-FREE-003', packageId: firstPackage.id, status: voucher_entity_1.VoucherStatus.UNUSED }),
                        voucherRepo.create({ businessId: demoBusinessId, code: 'DEMO-FREE-004', packageId: firstPackage.id, status: voucher_entity_1.VoucherStatus.UNUSED }),
                        voucherRepo.create({ businessId: demoBusinessId, code: 'DEMO-FREE-005', packageId: firstPackage.id, status: voucher_entity_1.VoucherStatus.UNUSED }),
                    ];
                    await voucherRepo.save(vouchers);
                    console.log(`Created ${vouchers.length} sample vouchers.`);
                }
                else {
                    console.log('Sample vouchers already exist, skipping.');
                }
            }
            else {
                console.log('Sample packages already exist, skipping.');
            }
        }
        console.log('');
        console.log('═══ SEED COMPLETED ═══');
        console.log('');
        console.log('Demo credentials:');
        console.log('  System Admin: admin@hotspot.com / Admin@123');
        console.log('  Business Owner: demo@hotspot.com / Demo@123');
        await dataSource.destroy();
        process.exit(0);
    }
    catch (error) {
        console.error('Seed failed:', error);
        process.exit(1);
    }
}
seed();
