const sequelize = require('../config/dbconnection');
const leadsModel = require('../models/leads');
const Admin = require('../models/admin');
const moment = require("moment");
const { portalName } = require("../constants/constant");
const {TwilioCallNotes} = require("../models/leads")
const TwilioCallModel = require('../models/twilioModel')

const getLeadsList = async (request,reply) => {
    try{
        const data = await leadsModel.getAllLeadAjax();
        if(data){
            reply.send({status:1,message:"Leads fetched successfully",result:data})
        }
        else{
            reply.send({status:0,message:"Error fetching leads data"})
        }
            // Useful $_POST Variables coming from the plugin
            // // $draw = $this->input->post("draw");//counter used by DataTables to ensure that the Ajax returns from server-side processing requests are drawn in sequence by DataTables
            // // $columns =$this->input->post('columns');//Get name of the sorting column from its index
            // // $orderByColumnIndex = null;
            // // $orderBy = false;
            // // $orderType = 'desc';
            // // if(!empty($_POST['order'])){
            // //     $orderByColumnIndex = $_POST['order'][0]['column'];// index of the sorting column (0 index based - i.e. 0 is the first record)
            // //     if($orderByColumnIndex!=1 && $orderByColumnIndex<4){
            // //         $orderBy = $columns[$orderByColumnIndex]['data'];//Get name of the sorting column from its index
            // //         $order = $this->input->post('order');
            // //         $orderType = $order[0]['dir']; // ASC or DESC
            // //     }
            // // }
            
            // // $start  = $this->input->post("start");//Paging first record indicator.
            // // $length = $this->input->post('length');//Number of records that the table can display in the current draw
            // // /* END of POST variables */
            
            // // $recordsTotal = $this->lead_model->get_all_lead_count();
            
            // // $search=$this->input->post("search");
            // // /* SEARCH CASE : Filtered data */
            // // if(!empty($search['value'])){
            // //     $count_columns=count($columns);
            // //     /* WHERE Clause for searching */
            // //     //for($i=0 ; $i<$count_columns;$i++){
            // //         //$column = $columns[$i]['data'];//we get the name of each column using its index from POST request
            // //         $where[]="l.name like '%".$search['value']."%'";
            // //         $where[]="l.phone like '%".$search['value']."%'";
            // //     //}
            // //     $where = " ".implode(" OR " , $where);// id like '%searchValue%' or name like '%searchValue%' ....
            // //     /* End WHERE */			
                
            // //     $recordsFiltered = $this->lead_model->get_all_lead_ajax_count($where);//Count of search result

            // //     /* SQL Query for search with limit and orderBy clauses*/
                
            // //     $data = $this->lead_model->get_all_lead_ajax($where,$orderBy, $orderType ,$start,$length);
            // // }
            // // /* END SEARCH */
            // // else {
            //     // $data = $this->lead_model->get_all_lead_ajax(false,$orderBy, $orderType ,$start,$length);;

            //     // $recordsFiltered = $recordsTotal;
            // // }
            
            // /* Response to client before JSON encoding */
            // // $response = array(
            // //     "draw" => intval($draw),
            // //     "recordsTotal" => $recordsTotal,
            // //     "recordsFiltered" => $recordsFiltered,
            // //     "data" => $data
            // // );
            
            // // $lead_page_data = array(
            // //        'lead_start' => $start,
            // //        'lead_length' => $length,
            // //        'lead_orderByColumnIndex' => $orderByColumnIndex,
            // //        'lead_orderType' => $orderType,
            // //     );
            // // $this->session->set_userdata($lead_page_data);
            
            // // echo json_encode($response);
    }
    catch(error){
        console.log("getLeadsList error",error)
        reply.send({status:500,message:"Server Error"})
    }
}

const getAddLeadsData = async (request,reply) => {
    let data={};
    data['industries'] = await Admin.getAllIndustries();
    data['lead_status'] = await leadsModel.getAllLeadStatus(1);
    data['states'] = await Admin.getAllStates();
    data['countries'] = await Admin.getAllCountries();
    // data['campaigns'] = $this->campaign_model->get_all_campaigns();
    return data
}

const addLead = async (request,reply) => {
    let leadData = {};
    let currentDate = Math.round(moment().valueOf() / 1000);
    leadData['name']=request.body.values.leadName;
    leadData['partner_name']= (request.body.values.partnerName) && request.body.values.partnerName;
    leadData['title']= (request.body.values.brand) && request.body.values.brand;
    leadData['website_url']= (request.body.values.website_url) && request.body.values.website_url;
    leadData['email_id']= (request.body.values.email) && request.body.values.email;
    leadData['phone'] = (request.body.values.phone) && String(request.body.values.phone).replace(/[^0-9]/g, '');
    leadData['address']= (request.body.values.address) && request.body.values.address;
    leadData['city']= (request.body.values.city) && request.body.values.city;
    leadData['state_id']= (request.body.values.state) && request.body.values.state;
    leadData['zip_code']= (request.body.values.zip_code) && request.body.values.zip_code;
    leadData['country']= (request.body.values.country) && request.body.values.country;
    leadData['lead_status']= (request.body.values.lead_status) && request.body.values.lead_status;
    leadData['source_id']= (request.body.values.source) && request.body.values.source;
    leadData['opportunity_amount']= (request.body.values.opportunity_amount) && request.body.values.opportunity_amount;
    leadData['industry_id']= (request.body.values.industry) && request.body.values.industry;
    leadData['description']= (request.body.values.description) && request.body.values.description;
    leadData['campaign_id']= (request.body.values.campaign) && request.body.values.campaign;
    leadData['industry_other']= (request.body.values.industry_other) && request.body.values.industry_other;
    leadData['constant_changes']= (request.body.values.constant_changes) && request.body.values.constant_changes;
    leadData['tracking_database']= (request.body.values.tracking_database) && request.body.values.tracking_database;
    leadData['marketing']= (request.body.values.marketing) && request.body.values.marketing;
    leadData['printing_and_labels']= (request.body.values.printing_and_labels) && request.body.values.printing_and_labels;
    leadData['marketplace_to_sell']= (request.body.values.marketplace_to_sell) && request.body.values.marketplace_to_sell;
    leadData['problem_with_industry']= (request.body.values.problem_with_industry) && request.body.values.problem_with_industry;
    leadData['is_seed_to_sale_software']= (request.body.values.is_seed_to_sale_software) && parseInt(request.body.values.is_seed_to_sale_software);
    leadData['is_receiving_newsletter']= (request.body.values.is_receiving_newsletter) && parseInt(request.body.values.is_receiving_newsletter);
    leadData['is_marketplace_to_sell']= (request.body.values.is_marketplace_to_sell) && parseInt(request.body.values.is_marketplace_to_sell);
    leadData['is_card_processing']= (request.body.values.is_card_processing) && parseInt(request.body.values.is_card_processing);
        
    leadData['added_by']=request.body.userId;
    leadData['added_time']=currentDate;
    leadData['updated_by']=request.body.userId;
    leadData['updated_time']=currentDate;
    leadData['status']=1;

    let notes = request.body.values.notes;

    let modelStatus = await leadsModel.addLead(leadData);
    if(modelStatus){
        let leadNotes = [];
        if(notes){
            for(const note of notes){
                if(note){
                    let inNote = {};
                    inNote['notes'] = note;
                    inNote['lead_id'] = modelStatus;
                    inNote['added_by'] = leadData['added_by'];
                    inNote['timestamp'] = currentDate;
                    inNote['status'] = 1;
                    leadNotes.push(inNote);
                }
            }
            if(leadNotes){
                let leadNotesResult = await leadsModel.batchInsertLeadNote(leadNotes);
            }
        }
        
        /*********************Notification Starts Here******************/
        // Notification
        let notificationMsg=`Lead ${leadData['name']} has been added to ${portalName}`;
        let notificationUrl="leads";

        // Alert to user
        const incrementResult_User = await Admin.incrementField(leadData.added_by,"noti_count",1);
        let notificationData_user = {
            user_id: leadData.added_by,
            url: notificationUrl,
            timestamp: currentDate,
            message: notificationMsg,
            status: 1,
            from_id: leadData.added_by,
        };
        const addNotificationResult_user = await Admin.addNotification(notificationData_user);

        // Alert to all admins
        let adminIds = await Admin.getAllAdminIds();
        let notificationData = {};
        for (const adminId of adminIds) {
            if (adminId != leadData.added_by) {
            const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
            notificationData = {
                user_id: adminId,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: leadData.added_by,
            };
            const addNotificationResult = await Admin.addNotification(notificationData);
            }
        }
        /*******************Notification Ends Here**********************************/
        reply.send({status:1, message:"Lead created successfully",notification:notificationMsg});
    }else{
        reply.send({status:0, message:"Failed to create Lead"});
    }
}

const getLeadById = async (request,reply) => {
    const {editId} = request.body;
    let data={};
    data['industries'] = await Admin.getAllIndustries();
    data['lead_status'] = await leadsModel.getAllLeadStatus(1);
    data['states'] = await Admin.getAllStates();
    data['countries'] = await Admin.getAllCountries();
    data['lead'] = await leadsModel.getLeadById(editId)
    data['call_notes'] = await leadsModel.getAllCallNotes(editId,"ASC",false);
    // data['campaigns'] = $this->campaign_model->get_all_campaigns();
    return data
}

const editLead = async (request,reply) => {
    try{
        let leadData = {};
        const id = request.body.editId;
        let currentDate = Math.round(moment().valueOf() / 1000);
        leadData['name']=request.body.values.leadName;
        leadData['partner_name']= (request.body.values.partnerName) && request.body.values.partnerName || null;
        leadData['title']= (request.body.values.brand) && request.body.values.brand || null;
        leadData['website_url']= (request.body.values.website_url) && request.body.values.website_url || null;
        leadData['email_id']= (request.body.values.email) && request.body.values.email || null;
        leadData['phone'] = (request.body.values.phone) && String(request.body.values.phone).replace(/[^0-9]/g, '') || null;
        leadData['address']= (request.body.values.address) && request.body.values.address || null;
        leadData['city']= (request.body.values.city) && request.body.values.city || null;
        leadData['state_id']= (request.body.values.state) && request.body.values.state || null;
        leadData['zip_code']= (request.body.values.zip_code) && request.body.values.zip_code || null;
        leadData['country']= (request.body.values.country) && request.body.values.country || null;
        leadData['lead_status']= (request.body.values.lead_status) && request.body.values.lead_status || null;
        leadData['source_id']= (request.body.values.source) && request.body.values.source || null;
        leadData['opportunity_amount']= (request.body.values.opportunity_amount) && request.body.values.opportunity_amount || null;
        leadData['industry_id']= (request.body.values.industry) && request.body.values.industry || null;
        leadData['description']= (request.body.values.description) && request.body.values.description || null;
        leadData['campaign_id']= (request.body.values.campaign) && request.body.values.campaign || null;
        leadData['industry_other']= (request.body.values.industry_other) && request.body.values.industry_other || null;
        leadData['constant_changes']= (request.body.values.constant_changes) && request.body.values.constant_changes || null;
        leadData['tracking_database']= (request.body.values.tracking_database) && request.body.values.tracking_database || null;
        leadData['marketing']= (request.body.values.marketing) && request.body.values.marketing || null;
        leadData['printing_and_labels']= (request.body.values.printing_and_labels) && request.body.values.printing_and_labels || null;
        leadData['marketplace_to_sell']= (request.body.values.marketplace_to_sell) && request.body.values.marketplace_to_sell || null;
        leadData['problem_with_industry']= (request.body.values.problem_with_industry) && request.body.values.problem_with_industry || null;
        leadData['is_seed_to_sale_software']= (request.body.values.is_seed_to_sale_software) && parseInt(request.body.values.is_seed_to_sale_software);
        leadData['is_receiving_newsletter']= (request.body.values.is_receiving_newsletter) && parseInt(request.body.values.is_receiving_newsletter);
        leadData['is_marketplace_to_sell']= (request.body.values.is_marketplace_to_sell) && parseInt(request.body.values.is_marketplace_to_sell);
        leadData['is_card_processing']= (request.body.values.is_card_processing) && parseInt(request.body.values.is_card_processing);

        leadData['updated_by']=request.body.userId;
        leadData['updated_time']=currentDate;
        leadData['status']=1;

        const modelStatus = await leadsModel.updateLead(id,leadData);

        let notesArray = request.body.values.notes;
        const notes = notesArray.map((item) => {
            if (typeof item === 'object' && item !== null && 'note' in item) {
              return item.note;
            } else if (typeof item === 'string') {
              return item;
            }
            return null;
          });
        let noteIds = request.body.values.idNote;
        let dataForDb=[];
        
        for(let i=0;i<notes.length;i++){
            dataForDb[i] = dataForDb[i] || {};
            if(noteIds[i]){
                dataForDb[i]['id']=noteIds[i];
            }else{
                dataForDb[i]['timestamp']=currentDate;
                dataForDb[i]['added_by']=leadData['updated_by'];
            }
            if(notes[i]){
                dataForDb[i]['lead_id']=id;
                dataForDb[i]['notes']=notes[i];
                dataForDb[i]['status']=1;
            }else{
                dataForDb[i]['notes']=notes[i];
                dataForDb[i]['status']=2;
            }
        }
        await leadsModel.updateBatchData(TwilioCallNotes,dataForDb);

        if(modelStatus){
            
            /*********************Notification Starts Here******************/
            // Notification
            let notificationMsg=`Lead ${leadData['name']} has been updated.`;
            let notificationUrl="leads";

            // Alert to user
            const incrementResult_User = await Admin.incrementField(leadData.updated_by,"noti_count",1);
            let notificationData_user = {
                user_id: leadData.updated_by,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: leadData.updated_by,
            };
            const addNotificationResult_user = await Admin.addNotification(notificationData_user);

            // Alert to all admins
            let adminIds = await Admin.getAllAdminIds();
            let notificationData = {};
            for (const adminId of adminIds) {
                if (adminId != leadData.updated_by) {
                const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
                notificationData = {
                    user_id: adminId,
                    url: notificationUrl,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: leadData.updated_by,
                };
                const addNotificationResult = await Admin.addNotification(notificationData);
                }
            }
            /*******************Notification Ends Here**********************************/
            reply.send({status:1, message : "Leads updated successfully",notification:notificationMsg});
        }
        else{
            reply.send({status:0, message : "Error updating leads"});
        }
    }
    catch(error){
        console.log(error);
    }
}

const deleteLead = async (request,reply) => {
    let {updateId,status,userId} = request.body;
    let currentDate = Math.round(moment().valueOf() / 1000);
    let updateData = {};
    let notificationMsg;
    updateData['status']=status;
    if(updateId){
        let deleted= await leadsModel.updateLead(updateId,updateData);
        let leadData= await leadsModel.getLeadById(updateId);
        if(updateData['status']===2)
        {
            notificationMsg=`The lead "${leadData[0].name}" has been deleted.`;
        }
        else if(updateData['status']===0)
        {
            notificationMsg=`The lead "${leadData[0].name}" has been made inactive.`;
        }
        else
        {
            notificationMsg=`The lead "${leadData[0].name}" has been made active.`;
        }
        if(deleted){
            // Notification
            let notificationUrl="leads";
            // Alert to user
            const incrementResult_User = await Admin.incrementField(userId,"noti_count",1);
            let notificationData_user = {
                user_id: userId,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: userId,
            };
            const addNotificationResult_user = await Admin.addNotification(notificationData_user);

            // Alert to all admins
            let adminIds = await Admin.getAllAdminIds();
            let notificationData = {};
            for (const adminId of adminIds) {
                if (adminId != userId) {
                const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
                notificationData = {
                    user_id: adminId,
                    url: notificationUrl,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: userId,
                };
                const addNotificationResult = await Admin.addNotification(notificationData);
                }
            }
            reply.send({status:1, message:notificationMsg});
        }else{
            reply.send({status:0, message:"Unable to delete the lead!"});
        }
    }
}

const deleteLeadNote = async (request,reply) => {
    let {noteId, leadId, userId} = request.body;
    let currentDate = Math.round(moment().valueOf() / 1000);
    let deleteStatus = await leadsModel.deleteLeadNote(noteId);
    let lead= await leadsModel.getLeadById(leadId);
    if (deleteStatus){
        // Notification
        let notificationMsg = `Note has been deleted from the lead "${lead['name']}"`;				
        let notificationUrl = `admin/lead/view-lead/${leadId}/0/3`;
        
        // Alert to all admins
        let adminIds = await Admin.getAllAdminIds();
        let notificationData = {};
        for (const adminId of adminIds) {
            const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
            notificationData = {
                user_id: adminId,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: userId,
            };
            const addNotificationResult = await Admin.addNotification(notificationData);
        }
        reply.send({status:1,message:'Note has been deleted successfully'});
    }else{
        reply.send({status:0,message:'Failed to delete note.'});
    }
}

const viewLead = async (request,reply) => {
    let {id} = request.body;
    let data = {};
    data['lead']= await leadsModel.getLeadById(id);
    data['states'] = await Admin.getAllStates();
    data['countries'] = await Admin.getAllCountries();
    data['industries'] = await Admin.getAllIndustries();
    // data['campaigns'] = $this->campaign_model->get_all_campaigns();
    data['call_notes'] = await leadsModel.getAllCallNotes(id,"ASC",false);
    if(data['lead']['phone']){
        data['twilio_calls'] = await TwilioCallModel.getAllCalls(` AND (tc.from = '+${data['lead']['phone']}' OR tc.to='+${data['lead']['phone']}')`,'ASC');
    }
    reply.send({status:1,message:"Data fetched successfully",result:data})
}

const leadStatus = async (request,reply) => {
    try{
        let leadStatus = await leadsModel.getAllLeadStatus(false);
        return leadStatus;
    }
    catch(error){
        console.log(error);
    }
}

const addLeadStatus = async (request,reply) => {
    let statusData = {};
    let currentDate = Math.round(moment().valueOf() / 1000);
    statusData['name']   = request.body.values.name;
    statusData['added_by']   = request.body.userId;
    statusData['timestamp']   = currentDate;
    statusData['status']   = 1;

    let modelStatus= await leadsModel.addLeadStatus(statusData);
    if(modelStatus){
        // Notification
        let notificationMsg=`Lead status "${statusData['name']}" has been added successfully.`;
        let notificationUrl="lead/lead-status";
        // Alert to user
        const incrementResult_User = await Admin.incrementField(statusData['added_by'],"noti_count",1);
        let notificationData_user = {
            user_id: statusData['added_by'],
            url: notificationUrl,
            timestamp: currentDate,
            message: notificationMsg,
            status: 1,
            from_id: statusData['added_by'],
        };
        const addNotificationResult_user = await Admin.addNotification(notificationData_user);

        // Alert to all admins
        let adminIds = await Admin.getAllAdminIds();
        let notificationData = {};
        for (const adminId of adminIds) {
            if (adminId != statusData['added_by']) {
            const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
            notificationData = {
                user_id: adminId,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: statusData['added_by'],
            };
            const addNotificationResult = await Admin.addNotification(notificationData);
            }
        }
        reply.send({status:1,message:"Lead status has been added successfully",notification:notificationMsg})
    }else{
        reply.send({status:0,message:"Failed to add lead status"});
    }
}

const editLeadStatus = async (request,reply) => {
    let {editId,userId} = request.body;
    let currentDate = Math.round(moment().valueOf() / 1000);
    let statusData = {};
    statusData['name']   = request.body.values.name;
    let modelStatus = await leadsModel.updateLeadStatus(editId,statusData);
    if(modelStatus){
        // Notification
        let notificationMsg=`The name of lead status "${statusData['name']}" has been updated.`;
        let notificationUrl="lead/lead-status";
        // Alert to user
        const incrementResult_User = await Admin.incrementField(userId,"noti_count",1);
        let notificationData_user = {
            user_id: userId,
            url: notificationUrl,
            timestamp: currentDate,
            message: notificationMsg,
            status: 1,
            from_id: userId,
        };
        const addNotificationResult_user = await Admin.addNotification(notificationData_user);

        // Alert to all admins
        let adminIds = await Admin.getAllAdminIds();
        let notificationData = {};
        for (const adminId of adminIds) {
            if (adminId != userId) {
            const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
            notificationData = {
                user_id: adminId,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: userId,
            };
            const addNotificationResult = await Admin.addNotification(notificationData);
            }
        }
        reply.send({status:1,message:`Lead status "${statusData['name']}" has been updated successfully`})
    }
    else{
        reply.send({status:0,message:`Failed to update lead status`})
    }
}

const deleteLeadStatus = async (request,reply) => {
    let {deleteId , status, userId} = request.body;
    let currentDate = Math.round(moment().valueOf() / 1000);
    let data = {};
    data['status']=status;
    let notificationMsg = "";
    if(deleteId){
        let deleted = await leadsModel.updateLeadStatus(deleteId,data);
        let statusData= await leadsModel.getLeadStatusById(deleteId);
        if(data['status']===2){
            notificationMsg=`The lead status "${statusData[0].name}" has been deleted.`;
        }else if(data['status']===0){
            notificationMsg=`The lead status "${statusData[0].name}" has been made inactive.`;
        }else{
            notificationMsg=`The lead status "${statusData[0].name}" has been made active.`;
        }

        if(deleted){
            // Notification
            let notificationUrl="lead/lead-status";
            // Alert to user
            const incrementResult_User = await Admin.incrementField(userId,"noti_count",1);
            let notificationData_user = {
                user_id: userId,
                url: notificationUrl,
                timestamp: currentDate,
                message: notificationMsg,
                status: 1,
                from_id: userId,
            };
            const addNotificationResult_user = await Admin.addNotification(notificationData_user);

            // Alert to all admins
            let adminIds = await Admin.getAllAdminIds();
            let notificationData = {};
            for (const adminId of adminIds) {
                if (adminId != userId) {
                const incrementResult = await Admin.incrementField(adminId,"noti_count",1);
                notificationData = {
                    user_id: adminId,
                    url: notificationUrl,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: userId,
                };
                const addNotificationResult = await Admin.addNotification(notificationData);
                }
            }
            reply.send({status:1,message:notificationMsg})
        }else{
            reply.send({status:0,message:"Unable to delete / Change status of the Lead Status!"});
        }
    }
}

const getLeadStatusById = async (request,reply) => {
    try{
        let id = request.body.id;
        let result = await leadsModel.getLeadStatusById(id)
        // console.log("result_________________________",result);
        if(result){
            if(result.length > 0){
                return result[0];
            }
        }
    }
    catch(error){
        console.log(error);
    }
}

module.exports = { getLeadsList, addLead, getAddLeadsData, getLeadById, editLead, deleteLeadNote, viewLead, deleteLead, 
    leadStatus, addLeadStatus, editLeadStatus, deleteLeadStatus, getLeadStatusById }