const asyncHandler = require('../middlewares/asyncHandler');
const { getLocationFilterFromRequest } = require('../utils/auditFilterHelper');
const {
  getAllSchedules,
  getScheduleById,
  createSchedule,
  updateSchedule,
  deleteSchedule,
  setAssignmentMailSent
} = require('../repositories/auditSchedulesRepository');
const { getUserById } = require('../repositories/userRepository');
const {
  buildAuditAssignmentMailBody,
  buildAuditReminderMailBody,
  sendTicketEmail
} = require('../services/emailService');

exports.getAllSchedules = asyncHandler(async (req, res) => {
  const filter = getLocationFilterFromRequest(req);
  const rows = await getAllSchedules(filter);
  res.status(200).json({ success: true, data: rows });
});

exports.getScheduleById = asyncHandler(async (req, res) => {
  const schedule = await getScheduleById(req.params.id);
  if (!schedule) {
    return res.status(404).json({ success: false, message: 'Schedule not found' });
  }
  res.status(200).json({ success: true, data: schedule });
});

exports.createSchedule = asyncHandler(async (req, res) => {
  const userId = req.user?.userId ?? req.user?.user_id;
  if (!userId) {
    return res.status(401).json({ success: false, message: 'Unauthorized' });
  }
  const {
    audit_name,
    assigned_to_user_id,
    scheduled_date,
    recurrence_type,
    recurrence_day_of_week,
    recurrence_day_of_month,
    reminder_days_before
  } = req.body;

  if (!audit_name || !assigned_to_user_id || !scheduled_date) {
    return res.status(400).json({
      success: false,
      message: 'audit_name, assigned_to_user_id, and scheduled_date are required'
    });
  }

  const id = await createSchedule({
    audit_name,
    assigned_to_user_id: Number(assigned_to_user_id),
    scheduled_date,
    recurrence_type: recurrence_type || 'once',
    recurrence_day_of_week: recurrence_day_of_week != null ? Number(recurrence_day_of_week) : null,
    recurrence_day_of_month: recurrence_day_of_month != null ? Number(recurrence_day_of_month) : null,
    reminder_days_before: reminder_days_before != null ? Number(reminder_days_before) : 0,
    created_by: userId
  });

  const schedule = await getScheduleById(id);
  const createdByUser = await getUserById(userId);
  const assignedUser = await getUserById(assigned_to_user_id);
  const toEmail = assignedUser?.email_id;
  const recurrenceLabel =
    recurrence_type === 'weekly'
      ? `Weekly (${['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][Number(recurrence_day_of_week)] || '?'})`
      : recurrence_type === 'monthly'
        ? `Monthly (day ${recurrence_day_of_month})`
        : 'One-time';

  if (toEmail) {
    const htmlBody = buildAuditAssignmentMailBody({
      auditName: audit_name,
      scheduledDate: scheduled_date,
      recurrenceType: recurrenceLabel,
      assignedToName: assignedUser?.employee_name,
      createdByName: createdByUser?.employee_name || 'System'
    });
    try {
      const outcome = await sendTicketEmail({
        to: toEmail,
        subject: `Audit scheduled: ${audit_name}`,
        htmlBody
      });
      if (outcome?.sent) {
        await setAssignmentMailSent(id);
      } else if (outcome?.skipped) {
        console.warn('[auditSchedules] Assignment email skipped:', outcome.reason);
      }
    } catch (err) {
      console.warn('[auditSchedules] Assignment email failed:', err.message);
    }
  }

  res.status(201).json({
    success: true,
    data: schedule,
    message: 'Schedule created successfully. Assignment email is sent when SMTP is configured.'
  });
});

exports.updateSchedule = asyncHandler(async (req, res) => {
  const existing = await getScheduleById(req.params.id);
  if (!existing) {
    return res.status(404).json({ success: false, message: 'Schedule not found' });
  }
  const {
    audit_name,
    assigned_to_user_id,
    scheduled_date,
    recurrence_type,
    recurrence_day_of_week,
    recurrence_day_of_month,
    reminder_days_before
  } = req.body;
  await updateSchedule(req.params.id, {
    audit_name: audit_name ?? existing.audit_name,
    assigned_to_user_id: assigned_to_user_id != null ? Number(assigned_to_user_id) : existing.assigned_to_user_id,
    scheduled_date: scheduled_date ?? existing.scheduled_date,
    recurrence_type: recurrence_type ?? existing.recurrence_type,
    recurrence_day_of_week: recurrence_day_of_week !== undefined ? (recurrence_day_of_week == null ? null : Number(recurrence_day_of_week)) : existing.recurrence_day_of_week,
    recurrence_day_of_month: recurrence_day_of_month !== undefined ? (recurrence_day_of_month == null ? null : Number(recurrence_day_of_month)) : existing.recurrence_day_of_month,
    reminder_days_before: reminder_days_before != null ? Number(reminder_days_before) : existing.reminder_days_before
  });
  const updated = await getScheduleById(req.params.id);
  res.status(200).json({ success: true, data: updated });
});

exports.deleteSchedule = asyncHandler(async (req, res) => {
  const existing = await getScheduleById(req.params.id);
  if (!existing) {
    return res.status(404).json({ success: false, message: 'Schedule not found' });
  }
  await deleteSchedule(req.params.id);
  res.status(200).json({ success: true, message: 'Schedule deleted' });
});

exports.sendReminder = asyncHandler(async (req, res) => {
  const schedule = await getScheduleById(req.params.id);
  if (!schedule) {
    return res.status(404).json({ success: false, message: 'Schedule not found' });
  }
  const toEmail = schedule.assigned_to_email;
  if (!toEmail) {
    return res.status(400).json({ success: false, message: 'Assigned user has no email' });
  }
  const scheduled = new Date(schedule.scheduled_date);
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  scheduled.setHours(0, 0, 0, 0);
  const daysUntil = Math.ceil((scheduled - today) / (24 * 60 * 60 * 1000));
  const htmlBody = buildAuditReminderMailBody({
    auditName: schedule.audit_name,
    scheduledDate: schedule.scheduled_date,
    daysUntil: daysUntil > 0 ? daysUntil : 0,
    assignedToName: schedule.assigned_to_name
  });
  try {
    const outcome = await sendTicketEmail({
      to: toEmail,
      subject: `Reminder: Audit scheduled – ${schedule.audit_name}`,
      htmlBody
    });
    if (outcome?.skipped) {
      return res.status(200).json({
        success: true,
        message: `Reminder not sent: ${outcome.reason || 'SMTP not configured'}. Set SMTP_* in SAT_backend/.env or SMTP_ENABLED=false to skip.`,
        emailSent: false
      });
    }
    if (outcome?.sent === false) {
      return res.status(200).json({
        success: true,
        message: outcome.error || 'Reminder email could not be sent',
        emailSent: false
      });
    }
    res.status(200).json({ success: true, message: 'Reminder email sent', emailSent: true });
  } catch (err) {
    console.warn('[auditSchedules] Reminder email failed:', err.message);
    res.status(200).json({
      success: true,
      message: `Reminder saved but email failed: ${err.message}`,
      emailSent: false
    });
  }
});
