import { Request, Response } from 'express';
import GeometryType from '../models/GeometryType.js';
import { IAppUser } from '../middleware/roleMiddleware.js';

interface AuthRequest extends Request {
    appUser?: IAppUser;
}

// Default geometry types to seed if none exist
const DEFAULT_TYPES = [
    { name: 'Guarda-corpo/escada', efficiencyLoss: 20 },
    { name: 'Vigas leves', efficiencyLoss: 20 },
    { name: 'Vigas médias', efficiencyLoss: 20 },
    { name: 'Vigas pesadas', efficiencyLoss: 20 },
    { name: 'Chaparia comum', efficiencyLoss: 20 },
    { name: 'Chapas de pisos (>0,5m²)', efficiencyLoss: 20 },
    { name: 'Calhas', efficiencyLoss: 20 },
    { name: 'Cantoneiras', efficiencyLoss: 20 },
    { name: 'Telhas', efficiencyLoss: 20 },
    { name: 'Tubulações (ret/red) <100mm', efficiencyLoss: 20 },
    { name: 'Tubulações (ret/red) >100mm', efficiencyLoss: 20 },
    { name: 'Peças diversas (outras)', efficiencyLoss: 20 }
];

export const getAllnames = async (req: AuthRequest, res: Response) => {
    try {
        const organizationId = req.appUser?.organizationId;
        const isGlobalAdmin = req.appUser?.email === 'admtracksteel@gmail.com';
        console.log(`[GeometryType] Fetching for org: ${organizationId}, globalAdmin: ${isGlobalAdmin}`);

        if (!organizationId && !isGlobalAdmin) {
            return res.status(400).json({ error: 'Organization ID missing' });
        }

        // Search for org-specific types OR orphan types (legacy)
        const query = isGlobalAdmin
            ? {}
            : { $or: [{ organizationId }, { organizationId: { $exists: false } }, { organizationId: null }] };

        let types = await GeometryType.find(query).sort({ name: 1 });

        // Auto-seed if empty AND we HAVE an organization (don't seed for global view)
        if (types.length === 0 && organizationId) {
            console.log(`[GeometryType] No types found. Seeding defaults...`);
            try {
                const seedData = DEFAULT_TYPES.map(t => ({ ...t, organizationId }));
                types = await GeometryType.insertMany(seedData) as any;
                console.log(`[GeometryType] Seeded ${types.length} types successfully.`);
            } catch (seedError) {
                console.error('[GeometryType] Seeding failed:', seedError);
                return res.json([]);
            }
        }

        res.json(types);
    } catch (error: unknown) {
        console.error('[GeometryType] Error in getAllnames:', error);
        const message = error instanceof Error ? error.message : 'Unknown error';
        res.status(500).json({ error: message });
    }
};

export const restoreDefaults = async (req: AuthRequest, res: Response) => {
    try {
        const organizationId = req.appUser?.organizationId;
        if (!organizationId) {
            return res.status(400).json({ error: 'Organization ID missing' });
        }

        // Delete all existing types for this org
        await GeometryType.deleteMany({ organizationId });

        // Insert defaults
        const seedData = DEFAULT_TYPES.map(t => ({ ...t, organizationId }));
        const types = await GeometryType.insertMany(seedData);

        res.json(types);
    } catch (error: unknown) {
        console.error('[GeometryType] Error in restoreDefaults:', error);
        const message = error instanceof Error ? error.message : 'Unknown error';
        res.status(500).json({ error: message });
    }
};

export const createType = async (req: AuthRequest, res: Response) => {
    try {
        const organizationId = req.appUser?.organizationId;
        const { name, efficiencyLoss } = req.body;

        if (!name) {
            return res.status(400).json({ error: 'Name is required' });
        }

        const newType = new GeometryType({
            name,
            efficiencyLoss: Number(efficiencyLoss) || 0,
            organizationId
        });

        const saved = await newType.save();
        res.status(201).json(saved);
    } catch (error: unknown) {
        const message = error instanceof Error ? error.message : 'Unknown error';
        if (message.includes('E11000')) {
            return res.status(409).json({ error: 'A geometry type with this name already exists' });
        }
        res.status(500).json({ error: message });
    }
};

export const updateType = async (req: AuthRequest, res: Response) => {
    try {
        const { id } = req.params;
        const organizationId = req.appUser?.organizationId;
        const isGlobalAdmin = req.appUser?.email === 'admtracksteel@gmail.com';
        const { name, efficiencyLoss } = req.body;

        const query = isGlobalAdmin
            ? { _id: id }
            : { _id: id, organizationId };

        const updated = await GeometryType.findOneAndUpdate(
            query,
            { name, efficiencyLoss: Number(efficiencyLoss) },
            { new: true }
        );

        if (!updated) {
            return res.status(404).json({ error: 'Record not found' });
        }

        res.json(updated);
    } catch (error: unknown) {
        const message = error instanceof Error ? error.message : 'Unknown error';
        res.status(500).json({ error: message });
    }
};

export const deleteType = async (req: AuthRequest, res: Response) => {
    try {
        const { id } = req.params;
        const organizationId = req.appUser?.organizationId;
        const isGlobalAdmin = req.appUser?.email === 'admtracksteel@gmail.com';

        const query = isGlobalAdmin
            ? { _id: id }
            : { _id: id, organizationId };

        const deleted = await GeometryType.findOneAndDelete(query);

        if (!deleted) {
            return res.status(404).json({ error: 'Record not found' });
        }

        res.status(204).send();
    } catch (error: unknown) {
        const message = error instanceof Error ? error.message : 'Unknown error';
        res.status(500).json({ error: message });
    }
};
