import { Controller, Delete, Get, Middleware, Post, Put } from '@overnightjs/core';
import { Request, Response } from 'express';
import { auth, AuthRequest } from '../middleware/auth';
import PlanService from '../services/PlanService';
import Subscription from '../models/Subscription';

@Controller('api/plans')
export class PlanController {

    /**
     * Get all plans
     * GET /api/plans
     */
    @Get('')
    async getAllPlans(req: Request, res: Response) {
        try {
            const allPlans = await PlanService.getAllPlans();
            res.status(200).json({
                success: true,
                data: allPlans,
            });
        } catch (error: any) {
            console.error('Error fetching plans:', error);
            res.status(500).json({
                success: false,
                error: error.message || 'Server error',
            });
        }
    }

    /**
     * Create a new plan
     * POST /api/plans
     */
    @Post('')
    @Middleware(auth)
    async createPlan(req: Request, res: Response) {
        try {
            const authReq = req as AuthRequest;
            if (authReq.user?.role !== 'admin') {
                res.status(403).json({ success: false, error: 'Only admins can create plans' });
                return;
            }

            const { title, price, period, features } = req.body;

            if (!title || title.trim().length === 0) {
                res.status(400).json({ success: false, error: 'Plan title is required' });
                return;
            }
            if (price === undefined || Number.isNaN(Number(price)) || Number(price) < 0) {
                res.status(400).json({ success: false, error: 'A valid price is required' });
                return;
            }
            if (!period) {
                res.status(400).json({ success: false, error: 'Plan period is required' });
                return;
            }

            const plan = await PlanService.createPlan({
                title: title.trim(),
                price: Number(price),
                period,
                features: Array.isArray(features) ? features.filter((f: string) => f.trim().length > 0) : [],
            });

            res.status(201).json({ success: true, data: plan });
        } catch (error: any) {
            console.error('Error creating plan:', error);
            res.status(400).json({ success: false, error: error.message || 'Server error' });
        }
    }

    /**
     * Update plan (all fields)
     * PUT /api/plans/:id
     */
    @Put(':id')
    @Middleware(auth)
    async updatePlan(req: Request, res: Response) {
        try {
            const authReq = req as AuthRequest;
            const role = authReq.user?.role;

            if (role !== 'admin') {
                res.status(403).json({
                    success: false,
                    error: 'Only admins can update plans',
                });
                return;
            }

            const { id } = req.params;
            const { title, price, period, features } = req.body;

            const updates: Record<string, any> = {};

            if (title !== undefined) {
                if (title.trim().length === 0) {
                    res.status(400).json({ success: false, error: 'Plan title cannot be empty' });
                    return;
                }
                updates.title = title.trim();
            }

            if (price !== undefined) {
                if (Number.isNaN(Number(price)) || Number(price) < 0) {
                    res.status(400).json({ success: false, error: 'A valid price is required' });
                    return;
                }
                updates.price = Number(price);
            }

            if (period !== undefined) {
                updates.period = period;
            }

            if (features !== undefined) {
                updates.features = Array.isArray(features) ? features.filter((f: string) => f.trim().length > 0) : [];
            }

            if (Object.keys(updates).length === 0) {
                res.status(400).json({ success: false, error: 'No valid fields to update' });
                return;
            }

            const updatedPlan = await PlanService.updatePlan(id, updates);
            res.status(200).json({
                success: true,
                data: updatedPlan,
            });
        } catch (error: any) {
            console.error('Error updating plan:', error);
            const statusCode = error.message?.includes('not found') ? 404 : 400;
            res.status(statusCode).json({
                success: false,
                error: error.message || 'Server error',
            });
        }
    }

    /**
     * Delete a plan
     * DELETE /api/plans/:id
     */
    @Delete(':id')
    @Middleware(auth)
    async deletePlan(req: Request, res: Response) {
        try {
            const authReq = req as AuthRequest;
            if (authReq.user?.role !== 'admin') {
                res.status(403).json({ success: false, error: 'Only admins can delete plans' });
                return;
            }

            const { id } = req.params;

            // Check if any active subscriptions use this plan
            const activeSubscriptions = await Subscription.countDocuments({
                planId: id,
                status: 'Active',
            });

            if (activeSubscriptions > 0) {
                res.status(400).json({
                    success: false,
                    error: `Cannot delete plan: ${activeSubscriptions} active subscription(s) are using it`,
                });
                return;
            }

            await PlanService.deletePlan(id);
            res.status(200).json({ success: true, data: { message: 'Plan deleted successfully' } });
        } catch (error: any) {
            console.error('Error deleting plan:', error);
            const statusCode = error.message?.includes('not found') ? 404 : 400;
            res.status(statusCode).json({
                success: false,
                error: error.message || 'Server error',
            });
        }
    }

    /**
     * Reset plans based on seed plans.
     * POST /api/plans/reset
     */
    @Post('reset')
    @Middleware(auth)
    async resetPlans(req: Request, res: Response) {
        try {
            const authReq = req as AuthRequest;
            if (authReq.user?.role !== 'admin') {
                res.status(403).json({ success: false, error: 'Only admins can reset plans' });
                return;
            }

            const result = await PlanService.resetPlansFromSeed();
            res.status(200).json({
                success: true,
                data: result,
            });
        } catch (error: any) {
            console.error('Error resetting plans:', error);
            res.status(500).json({
                success: false,
                error: error.message || 'Server error',
            });
        }
    }
}
