import { Op } from 'sequelize';
import { ClientManagement } from "../models/index.js";


// GET /clients
export const getAllClients = async (req, res) => {
    try {
        const {
            page   = 1,
            limit  = 5,
            source = '',
            search = '',
        } = req.query;

        const offset = (parseInt(page) - 1) * parseInt(limit);


        const where = {};

        if (source) {
            where.source = source;
        }

        if (search) {
            where[Op.or] = [
                { name:  { [Op.like]: `%${search}%` } },
                { email: { [Op.like]: `%${search}%` } },
            ];
        }


        const { count: totalFiltered, rows: clients } =
            await ClientManagement.findAndCountAll({
                where,
                limit:  parseInt(limit),
                offset,
                order:  [['date', 'DESC']],
            });


        const totalClients = await ClientManagement.count();

        const totalAmountResult = await ClientManagement.sum('amount');
        const totalAmount = totalAmountResult || 0;


        const thirtyDaysAgo = new Date();
        thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);

        const offlineClients = await ClientManagement.count({
            where: { date: { [Op.lt]: thirtyDaysAgo } },
        });

        return res.status(200).json({
            success: true,
            stats: {
                totalClients,
                totalAmount,
                offlineClients,
                filteredClients: totalFiltered,
            },
            pagination: {
                currentPage:  parseInt(page),
                totalPages:   Math.ceil(totalFiltered / parseInt(limit)),
                totalRecords: totalFiltered,
                limit:        parseInt(limit),
            },
            clients,
        });

    } catch (error) {
        return res.status(500).json({
            success: false,
            message: 'Failed to fetch clients',
            error:   error.message,
        });
    }
};

// GET /clients/:id
export const getClientById = async (req, res) => {
    try {
        const client = await ClientManagement.findByPk(req.params.id);

        if (!client) {
            return res.status(404).json({
                success: false,
                message: 'Client not found',
            });
        }

        return res.status(200).json({ success: true, client });

    } catch (error) {
        return res.status(500).json({
            success: false,
            message: 'Failed to fetch client',
            error:   error.message,
        });
    }
};

// POST /clients    
export const createClient = async (req, res) => {
    try {
        const { name, email, phone, date, source, amount, text_area } = req.body;
        if (!name || !email || !phone || !date || !source || !amount) {
            return res.status(400).json({
                success: false,
                message: 'All fields are required',
            });
        }

        const existing = await ClientManagement.findOne({ where: { email } });
        if (existing) {
            return res.status(409).json({
                success: false,
                message: 'A client with this email already exists',
            });
        }

        const client = await ClientManagement.create({
            name, email, phone, date, source, amount, text_area,
        });

        return res.status(201).json({
            success: true,
            message: 'Client added successfully',
            client,
        });

    } catch (error) {
   
        if (error.name === 'SequelizeValidationError') {
            return res.status(400).json({
                success: false,
                message: 'Validation failed',
                errors:  error.errors.map(e => ({
                    field:   e.path,
                    message: e.message,
                })),
            });
        }

        return res.status(500).json({
            success: false,
            message: 'Failed to create client',
            error:   error.message,
        });
    }
};

// PUT /clients/:id
export const updateClient = async (req, res) => {
    try {


        const client = await ClientManagement.findByPk(req.params.id);

        if (!client) {
            return res.status(404).json({
                success: false,
                message: 'Client not found',
            });
        }

        const { name, email, phone, date, source, amount, text_area } = req.body;

     
        const normalizePhone = (val) => String(val).replace(/\D/g, '');

        const alreadySame = {};

        if (name   && name   === client.name)                                   alreadySame.name   = name;
        if (email  && email  === client.email)                                  alreadySame.email  = email;
        if (phone  && normalizePhone(phone) === normalizePhone(client.phone))   alreadySame.phone  = phone;
        if (date   && date   === client.date)                                   alreadySame.date   = date;
        if (source && source === client.source)                                 alreadySame.source = source;
        if (amount && parseFloat(amount) === parseFloat(client.amount))         alreadySame.amount = amount;
        if (text_area && text_area === client.text_area)                        alreadySame.text_area = text_area;

        if (Object.keys(alreadySame).length === Object.keys(req.body).length) {
            return res.status(400).json({
                success:    false,
                message:    'No changes detected, already up to date',
                alreadySame,
            });
        }


        if (email && email !== client.email) {
            const duplicate = await ClientManagement.findOne({ where: { email } });
            if (duplicate) {
                return res.status(409).json({
                    success: false,
                    message: 'Another client with this email already exists',
                });
            }
        }

  
        await client.update({ name, email, phone, date, source, amount, text_area });

        return res.status(200).json({
            success: true,
            message: 'Client updated successfully',
            client,
        });

    } catch (error) {

        if (error.name === 'SequelizeValidationError') {
            return res.status(400).json({
                success: false,
                message: 'Validation failed',
                errors:  error.errors.map(e => ({
                    field:   e.path,
                    message: e.message,
                })),
            });
        }

        return res.status(500).json({
            success: false,
            message: 'Failed to update client',
            error:   error.message,
        });
    }
};

// DELETE /clients/:id
export const deleteClient = async (req, res) => {
    try {
        const client = await ClientManagement.findByPk(req.params.id);

        if (!client) {
            return res.status(404).json({
                success: false,
                message: 'Client not found',
            });
        }

        await client.destroy();

        return res.status(200).json({
            success: true,
            message: 'Client deleted successfully',
        });

    } catch (error) {
        return res.status(500).json({
            success: false,
            message: 'Failed to delete client',
            error:   error.message,
        });
    }
};