import Client from '../models/client.js';
import Login from '../models/login.js';
import UserMaster from '../models/userMaster.js';
import { successResponse, errorResponse } from '../utils/response.js';
import { Op } from 'sequelize';
import bcrypt from 'bcryptjs';

export const createClient = async (req, res) => {
  try {
    const { 
      client_name, 
      mobile, 
      landline, 
      email = '', 
      address, 
      details, 
      status = 1,
      // Login credentials for client admin
      admin_name,
      admin_member_id,
      admin_password
    } = req.body;
    
    if (!client_name || !mobile || !landline || !address || !details) {
      return errorResponse(res, 'Missing required client fields', 400);
    }

    // Check if login credentials are provided
    if (!admin_name || !admin_member_id || !admin_password) {
      return errorResponse(res, 'Missing required admin credentials (name, member_id, password)', 400);
    }

    const exists = await Client.findOne({ where: { client_name, mobile } });
    if (exists) return errorResponse(res, 'Client already exists with same name & mobile', 409);

    // Check if member_id already exists (must be unique across entire system)
    const existingLogin = await Login.findOne({ where: { member_id: admin_member_id } });
    if (existingLogin) {
      return errorResponse(res, `Member ID '${admin_member_id}' is already taken. Please choose a different member ID.`, 409);
    }

    // Get CLIENT_ADMIN role
    const clientAdminRole = await UserMaster.findOne({ where: { role_name: 'CLIENT_ADMIN' } });
    if (!clientAdminRole) {
      return errorResponse(res, 'CLIENT_ADMIN role not found in database', 500);
    }

    // Create client
    const client = await Client.create({ 
      client_name, 
      mobile, 
      landline, 
      email, 
      address, 
      details, 
      status 
    });

    // Hash password
    const hashedPassword = await bcrypt.hash(admin_password, 10);

    // Create client admin login account
    const adminLogin = await Login.create({
      member_id: admin_member_id,
      mobile_number: mobile, // Use client's mobile as admin's mobile
      password: hashedPassword,
      name: admin_name,
      role_id: clientAdminRole.id, // Use the id field from UserMaster
      client_id: client.id, // Link to the created client
      treelogy_id: null, // Client admin doesn't belong to specific project initially
      com_id: 1,
      security_no: '0',
      status: 'Y'
    });

    return successResponse(res, 201, 'Client and admin account created successfully', {
      client,
      admin_account: {
        member_id: adminLogin.member_id,
        name: adminLogin.name,
        role: 'CLIENT_ADMIN'
      }
    });
  } catch (error) {
    console.error('Error creating client:', error);
    // Check if it's a unique constraint violation
    if (error.name === 'SequelizeUniqueConstraintError') {
      return errorResponse(res, `Member ID '${req.body.admin_member_id}' is already taken. Please choose a different member ID.`, 409);
    }
    return errorResponse(res, 'Error creating client', 500, error.message);
  }
};

export const listClients = async (req, res) => {
  try {
    // compact dropdown for Treelogy form
    if (req.query.compact === 'true') {
      const rows = await Client.findAll({ attributes: ['id', 'client_name'], order: [['client_name', 'ASC']] });
      return successResponse(res, 200, 'OK', rows);
    }

    const { q = '' } = req.query;
    const where = q
      ? {
          [Op.or]: [
            { client_name: { [Op.iLike]: `%${q}%` } },
            { email: { [Op.iLike]: `%${q}%` } },
            { mobile: { [Op.iLike]: `%${q}%` } },
          ],
        }
      : undefined;

    const rows = await Client.findAll({ where, order: [['id', 'DESC']] });
    return successResponse(res, 200, 'OK', rows);
  } catch (error) {
    return errorResponse(res, 'Error listing clients', 500, error.message);
  }
};

export const getClientById = async (req, res) => {
  try {
    const row = await Client.findByPk(req.params.id);
    if (!row) return errorResponse(res, 'Client not found', 404);
    return successResponse(res, 200, 'OK', row);
  } catch (error) {
    return errorResponse(res, 'Error fetching client', 500, error.message);
  }
};

export const updateClient = async (req, res) => {
  try {
    const row = await Client.findByPk(req.params.id);
    if (!row) return errorResponse(res, 'Client not found', 404);

    const updatable = ['client_name','mobile','landline','email','address','details','status'];
    updatable.forEach(k => {
      if (req.body[k] !== undefined) row[k] = req.body[k];
    });

    await row.save();
    return successResponse(res, 200, 'Client updated', row);
  } catch (error) {
    return errorResponse(res, 'Error updating client', 500, error.message);
  }
};

export const deleteClient = async (req, res) => {
  try {
    const clientId = req.params.id;
    
    // Check if client exists
    const client = await Client.findByPk(clientId);
    if (!client) return errorResponse(res, 'Client not found', 404);
    
    // Check for associated users
    const userCount = await Login.count({ where: { client_id: clientId } });
    if (userCount > 0) {
      return errorResponse(
        res, 
        `Cannot delete client. ${userCount} user(s) are associated with this client. Please delete or reassign the users first.`, 
        400
      );
    }
    
    // Check for associated projects
    const projectCount = await Treelogy.count({ where: { client_id: clientId } });
    if (projectCount > 0) {
      return errorResponse(
        res, 
        `Cannot delete client. ${projectCount} project(s) are associated with this client. Please delete or reassign the projects first.`, 
        400
      );
    }
    
    // Safe to delete - no dependencies
    await Client.destroy({ where: { id: clientId } });
    return successResponse(res, 200, 'Client deleted successfully', { id: clientId });
    
  } catch (error) {
    console.error('Error deleting client:', error);
    
    // Handle foreign key constraint errors with helpful message
    if (error.name === 'SequelizeForeignKeyConstraintError' || error.message.includes('foreign key constraint')) {
      return errorResponse(
        res, 
        'Cannot delete client. This client has associated users or projects. Please delete or reassign them first.', 
        400
      );
    }
    
    return errorResponse(res, 'Error deleting client', 500, error.message);
  }
};
