import * as companyService from '../services/company.service.js';
import * as noteService from '../services/note.service.js';
import * as companyReminderService from '../services/company-reminder.service.js';
import * as companyEmailService from '../services/company-email.service.js';
import {
  logCompanyCreated,
  logCompanyDeleted,
  logCompanyUpdated,
  logCompanyUserAssigned,
  logCompanyUserRemoved,
  logCompanyReminderCreated,
  logCompanyReminderUpdated,
  logCompanyReminderDeleted,
} from '../services/audit.service.js';

/**
 * Get all companies
 * GET /api/companies?search=query
 * Members only see companies they are assigned to
 */
export const getAllCompanies = async (req, res, next) => {
  try {
    const { search } = req.query;
    const userId = req.user?.id;
    const userRole = req.user?.role;

    const companies = await companyService.getAllCompanies(search, userId, userRole);

    res.status(200).json({
      success: true,
      count: companies.length,
      data: companies,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get company by ID
 * GET /api/companies/:companyId
 */
export const getCompanyById = async (req, res, next) => {
  try {
    const { companyId } = req.params;

    const company = await companyService.getCompanyById(companyId);

    res.status(200).json({
      success: true,
      data: company,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get company email threads aggregated across user's email accounts
 * GET /api/companies/:companyId/email-threads
 */
export const getCompanyEmailThreads = async (req, res, next) => {
  try {
    const userId = req.userId;
    const { companyId } = req.params;

    // Ensure company exists
    await companyService.getCompanyById(companyId);

    const result = await companyEmailService.getCompanyEmailThreads(companyId, userId);

    res.status(200).json({
      success: true,
      data: result,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get unread email counts grouped by company for current user
 * GET /api/companies/email-unread
 */
export const getCompanyUnreadCounts = async (req, res, next) => {
  try {
    const userId = req.userId;
    const counts = await companyEmailService.getCompanyUnreadCounts(userId);

    res.status(200).json({
      success: true,
      data: counts,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get company with relations (projects, todos, notes)
 * GET /api/companies/:companyId/details
 */
export const getCompanyWithRelations = async (req, res, next) => {
  try {
    const { companyId } = req.params;

    const company = await companyService.getCompanyWithRelations(companyId);

    res.status(200).json({
      success: true,
      data: company,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Create new company
 * POST /api/companies
 * Body: { name, description, address, city, country, phone, email, website }
 */
export const createCompany = async (req, res, next) => {
  try {
    const userId = req.userId;
    const data = req.body;

    const company = await companyService.createCompany(userId, data);

    // Log audit event
    await logCompanyCreated(userId, company.id, company.name, req.ip, req.headers['user-agent']);

    res.status(201).json({
      success: true,
      data: company,
      message: 'Firma bola vytvorená',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Update company
 * PATCH /api/companies/:companyId
 * Body: { name, description, address, city, country, phone, email, website }
 */
export const updateCompany = async (req, res, next) => {
  try {
    const userId = req.userId;
    const { companyId } = req.params;
    const data = req.body;

    // Get old company for audit
    const oldCompany = await companyService.getCompanyById(companyId);

    const company = await companyService.updateCompany(companyId, data);

    // Log audit event
    await logCompanyUpdated(
      userId,
      companyId,
      { name: oldCompany.name },
      { name: company.name },
      req.ip,
      req.headers['user-agent']
    );

    res.status(200).json({
      success: true,
      data: company,
      message: 'Firma bola aktualizovaná',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Delete company
 * DELETE /api/companies/:companyId
 */
export const deleteCompany = async (req, res, next) => {
  try {
    const { companyId } = req.params;
    const userId = req.userId;

    // Get company info before deleting
    const company = await companyService.getCompanyById(companyId);
    const companyName = company?.name;

    const result = await companyService.deleteCompany(companyId);

    // Log audit event
    await logCompanyDeleted(userId, companyId, companyName, req.ip, req.headers['user-agent']);

    res.status(200).json({
      success: true,
      message: result.message,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get company notes
 * GET /api/companies/:companyId/notes
 */
export const getCompanyNotes = async (req, res, next) => {
  try {
    const { companyId } = req.params;

    const notes = await noteService.getNotesByCompanyId(companyId);

    res.status(200).json({
      success: true,
      count: notes.length,
      data: notes,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Add company note
 * POST /api/companies/:companyId/notes
 */
export const addCompanyNote = async (req, res, next) => {
  try {
    const userId = req.userId;
    const { companyId } = req.params;
    const { content, dueDate } = req.body;

    const note = await noteService.createNote(userId, {
      content,
      companyId,
      dueDate,
    });

    res.status(201).json({
      success: true,
      data: note,
      message: 'Poznámka bola pridaná',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Update company note
 * PATCH /api/companies/:companyId/notes/:noteId
 */
export const updateCompanyNote = async (req, res, next) => {
  try {
    const { noteId } = req.params;
    const { content, dueDate } = req.body;

    const note = await noteService.updateNote(noteId, {
      content,
      dueDate,
    });

    res.status(200).json({
      success: true,
      data: note,
      message: 'Poznámka bola aktualizovaná',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Delete company note
 * DELETE /api/companies/:companyId/notes/:noteId
 */
export const deleteCompanyNote = async (req, res, next) => {
  try {
    const { noteId } = req.params;

    const result = await noteService.deleteNote(noteId);

    res.status(200).json({
      success: true,
      message: result.message,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Company reminders
 * CRUD for /api/companies/:companyId/reminders
 */
export const getCompanyReminders = async (req, res, next) => {
  try {
    const { companyId } = req.params;

    const reminders = await companyReminderService.getRemindersByCompanyId(companyId);

    res.status(200).json({
      success: true,
      count: reminders.length,
      data: reminders,
    });
  } catch (error) {
    next(error);
  }
};

export const createCompanyReminder = async (req, res, next) => {
  try {
    const userId = req.userId;
    const { companyId } = req.params;
    const { description, dueDate, isChecked } = req.body;

    const reminder = await companyReminderService.createReminder(companyId, { description, dueDate, isChecked });

    // Log audit event
    await logCompanyReminderCreated(userId, reminder.id, companyId, dueDate, req.ip, req.headers['user-agent']);

    res.status(201).json({
      success: true,
      data: reminder,
      message: 'Reminder bol pridaný',
    });
  } catch (error) {
    next(error);
  }
};

export const updateCompanyReminder = async (req, res, next) => {
  try {
    const userId = req.userId;
    const { companyId, reminderId } = req.params;
    const { description, dueDate, isChecked } = req.body;

    // Get old reminder for audit
    const oldReminder = await companyReminderService.getReminderById(reminderId);

    const reminder = await companyReminderService.updateReminder(companyId, reminderId, { description, dueDate, isChecked });

    // Log audit event
    await logCompanyReminderUpdated(userId, reminderId, companyId, oldReminder?.dueDate, dueDate, req.ip, req.headers['user-agent']);

    res.status(200).json({
      success: true,
      data: reminder,
      message: 'Reminder bol aktualizovaný',
    });
  } catch (error) {
    next(error);
  }
};

export const deleteCompanyReminder = async (req, res, next) => {
  try {
    const userId = req.userId;
    const { companyId, reminderId } = req.params;

    // Get reminder for audit before deletion
    const reminder = await companyReminderService.getReminderById(reminderId);

    const result = await companyReminderService.deleteReminder(companyId, reminderId);

    // Log audit event
    await logCompanyReminderDeleted(userId, reminderId, companyId, reminder?.dueDate, req.ip, req.headers['user-agent']);

    res.status(200).json({
      success: true,
      message: result.message,
    });
  } catch (error) {
    next(error);
  }
};

export const getReminderSummary = async (req, res, next) => {
  try {
    const userId = req.user?.id;
    const userRole = req.user?.role;
    const summary = await companyReminderService.getReminderSummary(userId, userRole);
    res.status(200).json({
      success: true,
      data: summary,
    });
  } catch (error) {
    next(error);
  }
};

export const getReminderCountsByCompany = async (req, res, next) => {
  try {
    const userId = req.user?.id;
    const userRole = req.user?.role;
    const counts = await companyReminderService.getReminderCountsByCompany(userId, userRole);
    res.status(200).json({
      success: true,
      data: counts,
    });
  } catch (error) {
    next(error);
  }
};

export const getUpcomingReminders = async (req, res, next) => {
  try {
    const userId = req.user?.id;
    const userRole = req.user?.role;
    const reminders = await companyReminderService.getUpcomingReminders(userId, userRole);
    res.status(200).json({
      success: true,
      count: reminders.length,
      data: reminders,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Get company users (team members)
 * GET /api/companies/:companyId/users
 */
export const getCompanyUsers = async (req, res, next) => {
  try {
    const { companyId } = req.params;

    const users = await companyService.getCompanyUsers(companyId);

    res.status(200).json({
      success: true,
      count: users.length,
      data: users,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Assign user to company
 * POST /api/companies/:companyId/users
 * Body: { userId, role }
 */
export const assignUserToCompany = async (req, res, next) => {
  try {
    const currentUserId = req.userId;
    const { companyId } = req.params;
    const { userId, role } = req.body;

    // Get company name for audit
    const company = await companyService.getCompanyById(companyId);

    const assignment = await companyService.assignUserToCompany(companyId, userId, currentUserId, role);

    // Log audit event
    await logCompanyUserAssigned(
      currentUserId,
      companyId,
      userId,
      company.name,
      req.ip,
      req.headers['user-agent']
    );

    res.status(201).json({
      success: true,
      data: assignment,
      message: 'Používateľ bol priradený k firme',
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Remove user from company
 * DELETE /api/companies/:companyId/users/:userId
 */
export const removeUserFromCompany = async (req, res, next) => {
  try {
    const currentUserId = req.userId;
    const { companyId, userId } = req.params;

    // Get company name for audit
    const company = await companyService.getCompanyById(companyId);

    const result = await companyService.removeUserFromCompany(companyId, userId);

    // Log audit event
    await logCompanyUserRemoved(
      currentUserId,
      companyId,
      userId,
      company.name,
      req.ip,
      req.headers['user-agent']
    );

    res.status(200).json({
      success: true,
      message: result.message,
    });
  } catch (error) {
    next(error);
  }
};

/**
 * Update user role on company
 * PATCH /api/companies/:companyId/users/:userId
 * Body: { role }
 */
export const updateUserRoleOnCompany = async (req, res, next) => {
  try {
    const { companyId, userId } = req.params;
    const { role } = req.body;

    const assignment = await companyService.updateUserRoleOnCompany(companyId, userId, role);

    res.status(200).json({
      success: true,
      data: assignment,
      message: 'Rola používateľa bola aktualizovaná',
    });
  } catch (error) {
    next(error);
  }
};
