import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';

const DEMO_PREFIX = '[DEMO]';

/**
 * Admin routes for demo/testing operations
 * These should only be available in development or testing environments
 */
export async function adminRoutes(fastify: FastifyInstance) {
    // Auth check - require OWNER or ADMIN role
    fastify.addHook('onRequest', async (request, reply) => {
        try {
            await request.jwtVerify();
            const user = request.user as { role?: string };
            if (!['OWNER', 'ADMIN'].includes(user?.role || '')) {
                return reply.code(403).send({ error: 'Admin access required' });
            }
        } catch (err) {
            return reply.code(401).send({ error: 'Unauthorized' });
        }
    });

    /**
     * Reseed demo plants in a realistic layout
     * - Each batch stays in appropriate room based on stage
     * - Veg batches → Veg rooms, Flower batches → Flower rooms, etc.
     */
    fastify.post('/reseed-plants', async (request: FastifyRequest, reply: FastifyReply) => {
        const prisma = fastify.prisma;

        try {
            fastify.log.info('🌿 Reseeding plants in realistic layout...');

            // Clear existing plants
            await prisma.facilityPlant.deleteMany({});
            await prisma.facilityPosition.updateMany({
                data: { status: 'EMPTY' }
            });

            // Get all demo batches
            const batches = await prisma.batch.findMany({
                where: { name: { startsWith: DEMO_PREFIX } },
                orderBy: { startDate: 'asc' }
            });

            if (batches.length === 0) {
                return reply.code(400).send({
                    error: 'No demo batches found. Run seed-demo.js first.'
                });
            }

            // Section mapping by room type
            const sectionMapping: Record<string, string[]> = {
                VEG_PRIMARY: ['T1', 'T2', 'T3', 'T4'],
                MOTHER: ['M1', 'M2'],
                FLOWER_A: ['A1', 'A2', 'A3', 'A4', 'A5', 'A6'],
                FLOWER_B: ['B1', 'B2', 'B3', 'B4', 'B5', 'B6'],
                DRY: ['D1', 'D2'],
                CURE: ['C1', 'C2'],
            };

            const results: { batch: string; planted: number }[] = [];

            for (const batch of batches) {
                let targetSections: string[] = [];
                let fillPercentage = 0.85;

                switch (batch.stage) {
                    case 'CLONE_IN':
                    case 'VEGETATIVE':
                        targetSections = sectionMapping.VEG_PRIMARY;
                        fillPercentage = 0.9;
                        break;
                    case 'FLOWERING':
                        if (batch.strain === 'Gorilla Glue #4') {
                            targetSections = sectionMapping.FLOWER_A;
                        } else if (batch.strain === 'Wedding Cake') {
                            targetSections = sectionMapping.FLOWER_B;
                        } else {
                            targetSections = ['A4', 'A5', 'A6'];
                        }
                        fillPercentage = 0.95;
                        break;
                    case 'DRYING':
                        targetSections = sectionMapping.DRY;
                        fillPercentage = 0.6;
                        break;
                    case 'CURING':
                        targetSections = sectionMapping.CURE;
                        fillPercentage = 0.5;
                        break;
                    default:
                        continue;
                }

                // Get sections
                const sections = await prisma.facilitySection.findMany({
                    where: { code: { in: targetSections } },
                    include: { positions: true }
                });

                // Collect available positions
                let allPositions: any[] = [];
                for (const section of sections) {
                    const available = section.positions.filter((p: any) => p.status === 'EMPTY');
                    allPositions = allPositions.concat(
                        available.map((p: any) => ({ ...p, sectionCode: section.code }))
                    );
                }

                const targetCount = Math.min(
                    Math.floor(allPositions.length * fillPercentage),
                    batch.plantCount || allPositions.length
                );

                const plantsToCreate = [];
                const positionIds = [];

                for (let i = 0; i < targetCount && i < allPositions.length; i++) {
                    const pos = allPositions[i];
                    const tagPrefix = batch.strain?.substring(0, 2).toUpperCase() || 'XX';
                    const tagNumber = `1A4-${tagPrefix}-${batch.id.substring(0, 4).toUpperCase()}-${String(i + 1).padStart(4, '0')}`;

                    plantsToCreate.push({
                        tagNumber,
                        batchId: batch.id,
                        positionId: pos.id,
                        address: `${pos.sectionCode}-R${pos.row}-C${pos.column}`,
                        status: 'ACTIVE'
                    });
                    positionIds.push(pos.id);
                }

                if (plantsToCreate.length > 0) {
                    await prisma.facilityPlant.createMany({
                        data: plantsToCreate,
                        skipDuplicates: true
                    });
                    await prisma.facilityPosition.updateMany({
                        where: { id: { in: positionIds } },
                        data: { status: 'OCCUPIED' }
                    });
                }

                results.push({ batch: batch.name || batch.id, planted: plantsToCreate.length });
            }

            const totalPlants = await prisma.facilityPlant.count();

            return {
                success: true,
                message: 'Plants reseeded in realistic layout',
                totalPlants,
                batches: results
            };

        } catch (error) {
            fastify.log.error(error);
            return reply.code(500).send({
                error: 'Failed to reseed plants',
                details: error instanceof Error ? error.message : 'Unknown error'
            });
        }
    });
}
