import { FastifyInstance } from 'fastify';
import {
    generateMetrcLocationReport,
    detectMetrcDiscrepancies,
    syncPlantLocationToMetrc,
    bulkSyncLocationsToMetrc,
    formatAddressForMetrc
} from '../services/metrc.service';

export async function metrcRoutes(fastify: FastifyInstance) {
    // Auth middleware
    fastify.addHook('onRequest', async (request) => {
        try {
            await request.jwtVerify();
        } catch (err) {
            throw err;
        }
    });

    /**
     * GET /metrc/report
     * Generate METRC-format location report for all plants
     */
    fastify.get('/report', {
        handler: async (request, reply) => {
            try {
                const { propertyId } = request.query as any;
                const report = await generateMetrcLocationReport(propertyId);

                return {
                    generatedAt: new Date().toISOString(),
                    plantCount: report.length,
                    plants: report
                };
            } catch (error) {
                fastify.log.error(error);
                return reply.status(500).send({ error: 'Failed to generate METRC report' });
            }
        }
    });

    /**
     * POST /metrc/discrepancies
     * Detect discrepancies between local data and METRC
     * Body: { metrcData: [...] } - Array of METRC plant records
     */
    fastify.post('/discrepancies', {
        handler: async (request, reply) => {
            try {
                const { metrcData } = request.body as any;

                if (!metrcData || !Array.isArray(metrcData)) {
                    return reply.status(400).send({ error: 'metrcData array required' });
                }

                const discrepancies = await detectMetrcDiscrepancies(metrcData);

                return {
                    checkedAt: new Date().toISOString(),
                    totalDiscrepancies: discrepancies.length,
                    critical: discrepancies.filter(d => d.severity === 'CRITICAL').length,
                    high: discrepancies.filter(d => d.severity === 'HIGH').length,
                    medium: discrepancies.filter(d => d.severity === 'MEDIUM').length,
                    low: discrepancies.filter(d => d.severity === 'LOW').length,
                    discrepancies
                };
            } catch (error) {
                fastify.log.error(error);
                return reply.status(500).send({ error: 'Failed to detect discrepancies' });
            }
        }
    });

    /**
     * POST /metrc/sync/:plantId
     * Sync a single plant location to METRC
     */
    fastify.post('/sync/:plantId', {
        handler: async (request, reply) => {
            try {
                const { plantId } = request.params as any;
                const result = await syncPlantLocationToMetrc(plantId);

                if (!result.success) {
                    return reply.status(400).send({ error: result.error });
                }

                return { success: true, message: 'Plant location synced to METRC' };
            } catch (error) {
                fastify.log.error(error);
                return reply.status(500).send({ error: 'Failed to sync plant' });
            }
        }
    });

    /**
     * POST /metrc/sync-all
     * Bulk sync all plant locations to METRC
     */
    fastify.post('/sync-all', {
        handler: async (request, reply) => {
            try {
                const { propertyId } = request.body as any;
                const result = await bulkSyncLocationsToMetrc(propertyId);

                return {
                    success: true,
                    synced: result.synced,
                    errorCount: result.errors.length,
                    errors: result.errors.slice(0, 10) // Only return first 10 errors
                };
            } catch (error) {
                fastify.log.error(error);
                return reply.status(500).send({ error: 'Failed to bulk sync' });
            }
        }
    });

    /**
     * GET /metrc/export/csv
     * Export plant locations in CSV format for manual METRC upload
     */
    fastify.get('/export/csv', {
        handler: async (request, reply) => {
            try {
                const { propertyId } = request.query as any;
                const report = await generateMetrcLocationReport(propertyId);

                // Generate CSV
                const headers = ['Plant Tag', 'Location', 'Room', 'Section', 'Position'];
                const rows = report.map(p => [
                    p.tagNumber,
                    p.location,
                    p.room,
                    p.section || '',
                    p.position || ''
                ]);

                const csv = [
                    headers.join(','),
                    ...rows.map(r => r.join(','))
                ].join('\n');

                reply.header('Content-Type', 'text/csv');
                reply.header('Content-Disposition', `attachment; filename="metrc-locations-${new Date().toISOString().split('T')[0]}.csv"`);

                return csv;
            } catch (error) {
                fastify.log.error(error);
                return reply.status(500).send({ error: 'Failed to export CSV' });
            }
        }
    });

    /**
     * GET /metrc/audit
     * Generate audit report for compliance
     */
    fastify.get('/audit', {
        handler: async (request, reply) => {
            try {
                const { propertyId, startDate, endDate } = request.query as any;

                // Get plant location history for the date range
                const prisma = fastify.prisma;
                const history = await prisma.plantLocationHistory.findMany({
                    where: {
                        movedAt: {
                            gte: startDate ? new Date(startDate) : new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
                            lte: endDate ? new Date(endDate) : new Date()
                        }
                    },
                    include: {
                        plant: true
                    },
                    orderBy: { movedAt: 'desc' }
                });

                // Get current plant locations
                const currentReport = await generateMetrcLocationReport(propertyId);

                return {
                    generatedAt: new Date().toISOString(),
                    dateRange: {
                        start: startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
                        end: endDate || new Date().toISOString()
                    },
                    summary: {
                        totalPlants: currentReport.length,
                        totalMoves: history.length,
                        uniquePlantsMoved: new Set(history.map(h => h.plantId)).size
                    },
                    currentLocations: currentReport.slice(0, 100), // Limit for response size
                    recentMoves: history.slice(0, 50).map(h => ({
                        plantTag: h.plant.tagNumber,
                        from: h.fromAddress ? formatAddressForMetrc(h.fromAddress) : 'NEW',
                        to: formatAddressForMetrc(h.toAddress),
                        movedAt: h.movedAt,
                        reason: h.reason
                    }))
                };
            } catch (error) {
                fastify.log.error(error);
                return reply.status(500).send({ error: 'Failed to generate audit report' });
            }
        }
    });
}
