// Use SQLite instead of PostgreSQL
const db = require('../config/sqlite-db');
const bcrypt = require('bcrypt');
const crypto = require('crypto');

// Get all projects based on user role
const getAllProjects = async (req, res) => {
  try {
    let query;
    const userId = req.user.id;
    const userRole = req.user.role;

    // Super admin can see all projects
    if (userRole === 'super_admin') {
      query = 'SELECT * FROM projects ORDER BY created_at DESC';
      const projects = await db.query(query);
      return res.status(200).json(projects.rows);
    }
    
    // Admin can see only their projects
    if (userRole === 'admin') {
      query = 'SELECT * FROM projects WHERE created_by = $1 ORDER BY created_at DESC';
      const projects = await db.query(query, [userId]);
      return res.status(200).json(projects.rows);
    }
    
    // Guest can only see projects they have access to through permissions
    query = `
      SELECT p.* FROM projects p
      INNER JOIN project_permissions pp ON p.id = pp.project_id
      WHERE pp.user_id = $1
      ORDER BY p.created_at DESC
    `;
    const projects = await db.query(query, [userId]);
    return res.status(200).json(projects.rows);

  } catch (error) {
    console.error('Error getting projects:', error);
    res.status(500).json({ message: 'Server error while retrieving projects' });
  }
};

// Get project by ID
const getProjectById = async (req, res) => {
  try {
    const projectId = req.params.id;
    const userId = req.user.id;
    const userRole = req.user.role;
    
    let query;
    let params;

    // Super admin can access any project
    if (userRole === 'super_admin') {
      query = 'SELECT * FROM projects WHERE id = $1';
      params = [projectId];
    } 
    // Admin can only access their own projects
    else if (userRole === 'admin') {
      query = 'SELECT * FROM projects WHERE id = $1 AND created_by = $2';
      params = [projectId, userId];
    } 
    // Guest can only access projects they have permissions for
    else {
      query = `
        SELECT p.* FROM projects p
        INNER JOIN project_permissions pp ON p.id = pp.project_id
        WHERE p.id = $1 AND pp.user_id = $2
      `;
      params = [projectId, userId];
    }

    const project = await db.query(query, params);
    
    if (project.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found or not authorized' });
    }
    
    res.status(200).json(project.rows[0]);
  } catch (error) {
    console.error('Error getting project by ID:', error);
    res.status(500).json({ message: 'Server error while retrieving project' });
  }
};

// Create new project
const createProject = async (req, res) => {
  try {
    const { name, description, start_date, end_date, completion_percentage, notes } = req.body;
    const userId = req.user.id;
    
    const newProject = await db.query(
      `INSERT INTO projects (
        name, description, start_date, end_date, 
        completion_percentage, notes, created_by
      ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *`,
      [name, description, start_date, end_date, completion_percentage || 0, notes, userId]
    );
    
    res.status(201).json(newProject.rows[0]);
  } catch (error) {
    console.error('Error creating project:', error);
    res.status(500).json({ message: 'Server error while creating project' });
  }
};

// Update project
const updateProject = async (req, res) => {
  try {
    const projectId = req.params.id;
    const userId = req.user.id;
    const userRole = req.user.role;
    const { name, description, start_date, end_date, completion_percentage, notes } = req.body;
    
    // Check if project exists and user has rights
    let existingProject;
    
    if (userRole === 'super_admin') {
      existingProject = await db.query('SELECT * FROM projects WHERE id = $1', [projectId]);
    } else {
      existingProject = await db.query(
        'SELECT * FROM projects WHERE id = $1 AND created_by = $2', 
        [projectId, userId]
      );
    }
    
    if (existingProject.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found or not authorized to update' });
    }
    
    // Update project
    const updatedProject = await db.query(
      `UPDATE projects 
       SET name = $1, description = $2, start_date = $3, end_date = $4,
           completion_percentage = $5, notes = $6, updated_at = DATETIME('now')
       WHERE id = $7
       RETURNING *`,
      [
        name || existingProject.rows[0].name, 
        description || existingProject.rows[0].description,
        start_date || existingProject.rows[0].start_date,
        end_date || existingProject.rows[0].end_date,
        completion_percentage !== undefined ? completion_percentage : existingProject.rows[0].completion_percentage,
        notes || existingProject.rows[0].notes,
        projectId
      ]
    );
    
    res.status(200).json(updatedProject.rows[0]);
  } catch (error) {
    console.error('Error updating project:', error);
    res.status(500).json({ message: 'Server error while updating project' });
  }
};

// Delete project
const deleteProject = async (req, res) => {
  try {
    const projectId = req.params.id;
    const userId = req.user.id;
    const userRole = req.user.role;
    
    // Check if project exists and user has rights
    let existingProject;
    
    if (userRole === 'super_admin') {
      existingProject = await db.query('SELECT * FROM projects WHERE id = $1', [projectId]);
    } else {
      existingProject = await db.query(
        'SELECT * FROM projects WHERE id = $1 AND created_by = $2', 
        [projectId, userId]
      );
    }
    
    if (existingProject.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found or not authorized to delete' });
    }
    
    // Delete any share links first (foreign key constraint)
    await db.query('DELETE FROM project_shares WHERE project_id = $1', [projectId]);
    
    // Delete any permissions first (foreign key constraint)
    await db.query('DELETE FROM project_permissions WHERE project_id = $1', [projectId]);
    
    // Delete the project
    await db.query('DELETE FROM projects WHERE id = $1', [projectId]);
    
    res.status(200).json({ message: 'Project deleted successfully' });
  } catch (error) {
    console.error('Error deleting project:', error);
    res.status(500).json({ message: 'Server error while deleting project' });
  }
};

// Generate share link for a project
const generateShareLink = async (req, res) => {
  try {
    const projectId = req.params.id;
    const userId = req.user.id;
    const userRole = req.user.role;
    const { password } = req.body;
    
    // Check if project exists and user has rights
    let existingProject;
    
    if (userRole === 'super_admin') {
      existingProject = await db.query('SELECT * FROM projects WHERE id = $1', [projectId]);
    } else {
      existingProject = await db.query(
        'SELECT * FROM projects WHERE id = $1 AND created_by = $2', 
        [projectId, userId]
      );
    }
    
    if (existingProject.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found or not authorized to share' });
    }
    
    // Hash password
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(password, salt);
    
    // Generate unique share ID
    const shareId = crypto.randomBytes(16).toString('hex');
    
    // Check if a share already exists for this project
    const existingShare = await db.query(
      'SELECT * FROM project_shares WHERE project_id = $1',
      [projectId]
    );
    
    let shareLink;
    
    if (existingShare.rows.length > 0) {
      // Update existing share
      shareLink = await db.query(
        `UPDATE project_shares 
         SET share_id = $1, password = $2, updated_at = DATETIME('now')
         WHERE project_id = $3
         RETURNING *`,
        [shareId, hashedPassword, projectId]
      );
    } else {
      // Create new share
      shareLink = await db.query(
        `INSERT INTO project_shares (project_id, share_id, password)
         VALUES ($1, $2, $3)
         RETURNING *`,
        [projectId, shareId, hashedPassword]
      );
    }
    
    res.status(201).json({
      shareId: shareLink.rows[0].share_id,
      projectId: shareLink.rows[0].project_id,
      createdAt: shareLink.rows[0].created_at
    });
  } catch (error) {
    console.error('Error generating share link:', error);
    res.status(500).json({ message: 'Server error while generating share link' });
  }
};

// Get shared project without authentication
const getSharedProject = async (req, res) => {
  try {
    const shareId = req.params.shareId;
    
    // Find the share link
    const shareLink = await db.query(
      'SELECT * FROM project_shares WHERE share_id = $1',
      [shareId]
    );
    
    if (shareLink.rows.length === 0) {
      return res.status(404).json({ message: 'Shared project not found' });
    }
    
    // Get the project details
    const project = await db.query(
      'SELECT * FROM projects WHERE id = $1',
      [shareLink.rows[0].project_id]
    );
    
    if (project.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found' });
    }
    
    // Return basic project information (requires password verification for full details)
    res.status(200).json({
      id: project.rows[0].id,
      name: project.rows[0].name,
      requiresPassword: true
    });
  } catch (error) {
    console.error('Error retrieving shared project:', error);
    res.status(500).json({ message: 'Server error while retrieving shared project' });
  }
};

// Get share information for a project
const getProjectShareInfo = async (req, res) => {
  try {
    const projectId = req.params.id;
    const userId = req.user.id;
    const userRole = req.user.role;
    
    // Check if project exists and user has rights
    let existingProject;
    
    if (userRole === 'super_admin') {
      existingProject = await db.query('SELECT * FROM projects WHERE id = $1', [projectId]);
    } else {
      existingProject = await db.query(
        'SELECT * FROM projects WHERE id = $1 AND created_by = $2', 
        [projectId, userId]
      );
    }
    
    if (existingProject.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found or not authorized' });
    }
    
    // Get share information
    const shareInfo = await db.query(
      'SELECT * FROM project_shares WHERE project_id = $1',
      [projectId]
    );
    
    if (shareInfo.rows.length === 0) {
      return res.status(404).json({ message: 'No share link exists for this project' });
    }
    
    res.status(200).json({
      shareId: shareInfo.rows[0].share_id,
      projectId: shareInfo.rows[0].project_id,
      createdAt: shareInfo.rows[0].created_at
    });
  } catch (error) {
    console.error('Error getting share info:', error);
    res.status(500).json({ message: 'Server error while retrieving share information' });
  }
};

// Verify share password
const verifySharePassword = async (req, res) => {
  try {
    const shareId = req.params.shareId;
    const { password } = req.body;
    
    // Find the share link
    const shareLink = await db.query(
      'SELECT * FROM project_shares WHERE share_id = $1',
      [shareId]
    );
    
    if (shareLink.rows.length === 0) {
      return res.status(404).json({ message: 'Shared project not found' });
    }
    
    // Verify password
    const isMatch = await bcrypt.compare(password, shareLink.rows[0].password);
    
    if (!isMatch) {
      return res.status(401).json({ message: 'Invalid password' });
    }
    
    // Get the full project details
    const project = await db.query(
      'SELECT * FROM projects WHERE id = $1',
      [shareLink.rows[0].project_id]
    );
    
    if (project.rows.length === 0) {
      return res.status(404).json({ message: 'Project not found' });
    }
    
    // Return full project details
    res.status(200).json(project.rows[0]);
  } catch (error) {
    console.error('Error verifying share password:', error);
    res.status(500).json({ message: 'Server error while verifying password' });
  }
};

// Get all projects with their share info (for admin's shareable projects page)
const getAllShareableProjects = async (req, res) => {
  try {
    const userId = req.user.id;
    const userRole = req.user.role;
    
    let projectsQuery;
    let projectsParams = [];
    
    // Super admin can share all projects
    if (userRole === 'super_admin') {
      projectsQuery = 'SELECT * FROM projects ORDER BY created_at DESC';
    } else if (userRole === 'admin') {
      // Admin can only share their own projects
      projectsQuery = 'SELECT * FROM projects WHERE created_by = $1 ORDER BY created_at DESC';
      projectsParams = [userId];
    } else {
      // Guests cannot share projects
      return res.status(403).json({ message: 'Not authorized to access shareable projects' });
    }
    
    const projects = await db.query(projectsQuery, projectsParams);
    
    // For each project, check if it has share information
    const projectsWithShareInfo = await Promise.all(projects.rows.map(async (project) => {
      try {
        const shareInfo = await db.query('SELECT share_id, created_at FROM project_shares WHERE project_id = $1', [project.id]);
        
        return {
          ...project,
          shareInfo: shareInfo.rows.length > 0 ? {
            shareId: shareInfo.rows[0].share_id,
            createdAt: shareInfo.rows[0].created_at
          } : null
        };
      } catch (err) {
        console.error(`Error getting share info for project ${project.id}:`, err);
        return {
          ...project,
          shareInfo: null
        };
      }
    }));
    
    res.status(200).json(projectsWithShareInfo);
  } catch (error) {
    console.error('Error getting shareable projects:', error);
    res.status(500).json({ message: 'Server error while retrieving shareable projects' });
  }
};

module.exports = {
  getAllProjects,
  getProjectById,
  createProject,
  updateProject,
  deleteProject,
  generateShareLink,
  getProjectShareInfo,
  getSharedProject,
  verifySharePassword,
  getAllShareableProjects
};
