// notifications.js
const postgresLogger = require('./postgres');
const { getDb } = require('./database');
const emailNotifications = require('./email-notifications');

async function sendTaskNotifications(type, taskId, taskTitle, taskDescription, authorId, comment = '', status = '', userName = '') {
    try {
        const db = getDb();
        if (!db) {
            console.log('❌ База данных не доступна для отправки уведомлений');
            return;
        }

        console.log(`📢 Начинаем отправку уведомлений для задачи ${taskId}:`);
        console.log(`   Тип: ${type}, Автор действия: ${authorId}, Название: ${taskTitle}`);

        // Получаем заказчика
        const creator = await new Promise((resolve, reject) => {
            db.get(`
                SELECT t.created_by as user_id, u.name as user_name, u.login as user_login, u.email
                FROM tasks t
                LEFT JOIN users u ON t.created_by = u.id
                WHERE t.id = ?
            `, [taskId], (err, row) => {
                if (err) reject(err);
                else resolve(row);
            });
        });

        // Получаем исполнителей
        const assignees = await new Promise((resolve, reject) => {
            db.all(`
                SELECT ta.user_id, u.name as user_name, u.login as user_login, u.email
                FROM task_assignments ta
                LEFT JOIN users u ON ta.user_id = u.id
                WHERE ta.task_id = ?
            `, [taskId], (err, rows) => {
                if (err) reject(err);
                else resolve(rows || []);
            });
        });

        // Получаем информацию об авторе действия
        const author = await new Promise((resolve, reject) => {
            db.get("SELECT name, login, email FROM users WHERE id = ?", [authorId], (err, row) => {
                if (err) reject(err);
                else resolve(row);
            });
        });

        const authorName = author ? author.name : 'Система';
        const authorLogin = author ? author.login : 'system';
        
        // Логируем в PostgreSQL (если настроено)
        let postgresLogIds = [];
        if (postgresLogger.initialized) {
            postgresLogIds = await logNotificationToPostgres({
                type,
                taskId,
                taskTitle,
                taskDescription,
                authorId,
                authorName,
                authorLogin,
                participants: [...(creator ? [{...creator, role: 'creator'}] : []), ...assignees.map(a => ({...a, role: 'assignee'}))],
                comment,
                status,
                userName
            });
        }

        // Отправляем email уведомления
        const participants = [...(creator ? [creator] : []), ...assignees].filter(p => p.user_id !== authorId);
        
        for (const participant of participants) {
            const taskData = {
                taskId,
                title: taskTitle,
                description: taskDescription,
                due_date: null, // Можно добавить получение срока из БД
                author_name: authorName,
                comment: comment,
                status: status,
                user_name: userName || participant.user_name,
                hours_left: type === 'deadline' ? 24 : null // Для уведомлений о дедлайне
            };

            await emailNotifications.sendTaskNotification(
                participant.user_id,
                taskData,
                type
            );
        }

        console.log(`✅ Уведомления отправлены для задачи ${taskId}`);

    } catch (error) {
        console.error('❌ Общая ошибка при обработке уведомлений:', error);
    }
}

// Обновим функцию для уведомлений о дедлайнах
async function sendDeadlineNotification(assignment, hoursLeft) {
    try {
        const taskData = {
            taskId: assignment.task_id,
            title: assignment.title,
            description: assignment.description || '',
            due_date: assignment.due_date,
            author_name: assignment.creator_name,
            hours_left: hoursLeft
        };

        // Отправляем уведомление исполнителю
        await emailNotifications.sendTaskNotification(
            assignment.user_id,
            taskData,
            'deadline'
        );

        // Отправляем уведомление заказчику
        await emailNotifications.sendTaskNotification(
            assignment.created_by,
            taskData,
            'deadline'
        );

        console.log(`✅ Email уведомление о сроке (${hoursLeft}ч) отправлено для задачи ${assignment.task_id}`);

    } catch (error) {
        console.error('❌ Ошибка отправки email уведомления о сроке:', error);
    }
}

async function checkUpcomingDeadlines() {
    const now = new Date();
    const in48Hours = new Date(now.getTime() + 48 * 60 * 60 * 1000).toISOString();
    const in24Hours = new Date(now.getTime() + 24 * 60 * 60 * 1000).toISOString();
    const nowISO = now.toISOString();

    const query = `
        SELECT DISTINCT ta.*, t.title, t.description, t.created_by, u.name as user_name, u.email as user_email,
               creator.name as creator_name, creator.email as creator_email
        FROM task_assignments ta
        JOIN tasks t ON ta.task_id = t.id
        JOIN users u ON ta.user_id = u.id
        JOIN users creator ON t.created_by = creator.id
        WHERE ta.due_date IS NOT NULL 
        AND ta.due_date > ?
        AND ta.due_date <= ?
        AND ta.status NOT IN ('completed', 'overdue')
        AND t.status = 'active'
        AND t.closed_at IS NULL
    `;

    const db = getDb();
    if (!db) {
        console.error('❌ База данных не доступна для проверки сроков');
        return;
    }

    db.all(query, [nowISO, in48Hours], async (err, assignments) => {
        if (err) {
            console.error('❌ Ошибка при проверке сроков задач:', err);
            return;
        }

        for (const assignment of assignments) {
            const dueDate = new Date(assignment.due_date);
            const timeLeft = dueDate.getTime() - now.getTime();
            const hoursLeft = Math.floor(timeLeft / (60 * 60 * 1000));

            if (hoursLeft <= 48 && hoursLeft > 24) {
                await sendDeadlineNotification(assignment, 48);
            } else if (hoursLeft <= 24) {
                await sendDeadlineNotification(assignment, 24);
            }
        }
    });
}

// Вспомогательные функции для работы с PostgreSQL
async function logNotificationToPostgres(data) {
    try {
        const {
            type,
            taskId,
            taskTitle,
            taskDescription,
            authorId,
            authorName,
            authorLogin,
            participants = [],
            comment = '',
            status = '',
            userName = '',
            error = ''
        } = data;

        // Создаем сообщение
        let messageContent = '';
        switch (type) {
            case 'created':
                messageContent = `Создана новая задача: ${taskTitle}`;
                break;
            case 'updated':
                messageContent = `Обновлена задача: ${taskTitle}`;
                break;
            case 'rework':
                messageContent = `Задача возвращена на доработку: ${taskTitle}. Комментарий: ${comment}`;
                break;
            case 'closed':
                messageContent = `Задача закрыта: ${taskTitle}`;
                break;
            case 'status_changed':
                messageContent = `Изменен статус задачи: ${taskTitle}. Новый статус: ${getStatusText(status)}`;
                break;
        }

        // Логируем для каждого получателя отдельно
        const recipientsToNotify = participants.filter(p => p.user_id !== authorId);
        const logIds = [];

        for (const recipient of recipientsToNotify) {
            const logId = await postgresLogger.logNotification({
                taskId,
                taskTitle,
                taskDescription,
                notificationType: type,
                authorId,
                authorName,
                authorLogin,
                recipientId: recipient.user_id,
                recipientName: recipient.user_name,
                recipientLogin: recipient.user_login,
                messageContent: `${messageContent}\n\nЗадача: ${taskTitle}\nОписание: ${taskDescription || 'Без описания'}\nАвтор: ${authorName}`,
                messageSubject: getNotificationSubject(type, taskTitle),
                deliveryMethods: ['email', 'telegram', 'vk'],
                comments: error ? `Ошибка: ${error}` : comment
            });

            if (logId) {
                logIds.push(logId);
            }
        }

        return logIds;

    } catch (error) {
        console.error('❌ Ошибка логирования в PostgreSQL:', error);
        return [];
    }
}

async function updatePostgresLogStatus(logIds, status, errorMessage = null, sentAt = null) {
    if (!logIds || logIds.length === 0) return;

    for (const logId of logIds) {
        await postgresLogger.updateNotificationStatus(logId, status, errorMessage, sentAt);
    }
}

function getNotificationSubject(type, taskTitle) {
    switch (type) {
        case 'created':
            return `Новая задача: ${taskTitle}`;
        case 'updated':
            return `Обновлена задача: ${taskTitle}`;
        case 'rework':
            return `Задача возвращена на доработку: ${taskTitle}`;
        case 'closed':
            return `Задача закрыта: ${taskTitle}`;
        case 'status_changed':
            return `Изменен статус задачи: ${taskTitle}`;
        default:
            return `Уведомление по задаче: ${taskTitle}`;
    }
}

function getStatusText(status) {
    const statusMap = {
        'assigned': 'Назначена',
        'in_progress': 'В работе',
        'completed': 'Завершена',
        'overdue': 'Просрочена',
        'rework': 'На доработке'
    };
    return statusMap[status] || status;
}

// Экспортируем функции
module.exports = {
    sendTaskNotifications,
    checkUpcomingDeadlines,
    sendDeadlineNotification,
    getStatusText,
    emailNotifications // Экспортируем для доступа к методам
};