const dbConnect   = require('../configs/dbConnection');
const {sendOtp, verifyOtp} = require('../../smsapi/model/smsModel');
const cancelTicketModel = require('../model/cancelTicketModel');
const cancellationDataModel = require('../model/cancellationDataModel');
const { ticketCancellationEmailModel } = require('../../emailapi/model/cancellationEmailModel');


exports.verifyUserforCancelation = async (req, res) => {
    
    const {ticket ,mobile, email} = req.body;
    console.log(mobile, email, ticket);
   
    if (!mobile || !email || !ticket) {
        return res.status(400).json({ error: 'moble number, email Id and Ticket Id are mandatory' });
    };

    const trimmedMobleNo = mobile.trim();
    const trimmedemailId = email.trim();
    const trimmedticketId = ticket.trim();
    
    const formattedMobleNo = '+91' + trimmedMobleNo.replace(/\D/g, '').replace(/^0|^91/, '');
    //   console.log(formattedMobleNo);  
  
    try {
   
        const [bookingDetails] = await dbConnect.query(
            `SELECT * 
            FROM uticket 
            WHERE tin_ticket = ? 
            AND pemail = ? 
            AND pmobile = ?`,
            [trimmedticketId, trimmedemailId, trimmedMobleNo]
        );

  
        if (!bookingDetails.length) {
        return res.status(404).json({ error: 'No booking found matching the provided details.' });
        } 
        // console.log([bookingDetails]);
        const sendOtpResponse = await sendOtp(formattedMobleNo, "BOBROSOTP" );
    
        // console.log(sendOtpResponse);
        res.status(200).json({sendOtpResponse});
    } catch (error) {
        console.error('Error ticked details:', error.message);
        res.status(500).json({ error: 'Failed to get cancellation data' });
    }
};



exports.cancellationData = async (req, res) => {
  try {
    const { mobile, otp, ticketId } = req.body;
    if (!mobile || !otp || !ticketId) {
      return res.status(400).json({ error: 'mobile, otp and ticketId are required' });
    }
    console.log(mobile, otp, ticketId);
    console.log(typeof mobile, typeof otp, typeof ticketId);
    const mob = mobile.trim();
    const trimmedOtp = otp.trim();
    // const trimmedOtp = String(otp).trim();
    const tid = ticketId.trim();

    // Verify OTP
    const verifyOtpResponse = await verifyOtp(mob, trimmedOtp);
    
    
    // if (!verifyOtpResponse || verifyOtpResponse.error) {
    //   return res.status(400).json({ error: 'Invalid or expired OTP' });
    // }
    
    if (verifyOtpResponse.Details === "OTP Mismatch") {
        console.log("verifyOtpResponseFor Check:", verifyOtpResponse.Details );
        return res.status(404). json({error: 'OTP verfication failed!'});
        };
   
    

    // Fetch cancellation data via API call
    const cancellationData = await cancellationDataModel.cancellationData(tid);

    return res.status(200).json({ success: true, cancellationData });
  } catch (error) {
       console.error('cancellation data error:', error);
    
    
    if (error.isSeatSellerError) {
     
      console.log(error.message);
      res.status(error.status || 500).json({
        success: false,
        message: error.message,
      });
    } else {
      console.log(error.message);
      res.status(500).json({ 
        success: false,
        message: 'Server error occurred while processing ticket cancellation data',
        ...(process.env.NODE_ENV === 'development' && { error: error.message })
      });
    }
  }
};


exports.cancelTicket = async (req, res) => {
  
    const { tin, seatsToCancel } = req.body;
    //console.log(tin, seatsToCancel);

    const cancelTicketData = {tin, seatsToCancel};

    try {
        const cancelTicketResponse = await cancelTicketModel.cancelTicketRequest(cancelTicketData);
        console.log(cancelTicketResponse)
      
          const refundAmount  = parseFloat(cancelTicketResponse.refundAmount)  || 0;
       const cancelationChrg = parseFloat(cancelTicketResponse.cancellationCharge) || 0;
       
        
        // const cancelationChrg = 50;
        // const refundAmount = 527.5;
        // const cancelTicketResponse = true;
        
         const costOfTicketC = parseFloat(
         (refundAmount + cancelationChrg).toFixed(2)
       );
        if (cancelTicketResponse) {
            // fetch booking details
            const [bookingRows] = await dbConnect.query(
            `SELECT uid, pemail, pmobile, blk_ticket, pseatno, fare, tcost
            FROM uticket 
            WHERE tin_ticket = ?`,
            [tin]
        );
    
        if (!bookingRows.length) {
            return res.status(404).json({ error: 'Ticket not found with given tin' });
        }

        // Destructure values (including pemail) up front
        const { uid, pemail, pmobile, blk_ticket, pseatno, fare, tcost  } = bookingRows[0];
    
        //console.log("CANCADW: ",blk_ticket )

        // fetch existing balance
        const [balRows] = await dbConnect.query(
            `SELECT ubal 
            FROM ulogin 
            WHERE uid = ?`,
            [uid]
        );
        let ubal = parseFloat(balRows?.[0]?.ubal ?? 0);
        ubal= ubal = Number(ubal.toFixed(2));
        

        
        let reversal_offer = 0;

        // allow us to adjust later
        let refundAmt = parseFloat(parseFloat(refundAmount).toFixed(2));

        
        const isLoggedInUser = String(uid).startsWith('1');
        console.log(isLoggedInUser ? '✅ Logged-in user' : '❌ Guest user');

        const datetime = new Date();
        const cancelRef = `${tin}_cancellation`;
    
        const pseatnocount = pseatno.split(',').length;
        console.log(pseatnocount); 

        const FractionC = parseFloat((costOfTicketC / tcost).toFixed(2));



        if (isLoggedInUser) {
            // credit refund
            const newbal = Number((ubal + refundAmt).toFixed(2));
       
            await dbConnect.query(
            `INSERT INTO t_account 
            (bal, id, treference, tamount_dr, tamount_cr, newbal, datetime) 
            VALUES (?, ?, ?, ?, ?, ?, ?)`,
            [ubal, uid, cancelRef, 0, refundAmt, newbal, datetime]
            );

            // fetch discount
            const [offerRows] = await dbConnect.query(
                `SELECT discount 
                FROM offeruse 
                WHERE blk_ticket = ?
                AND offercode = ?
                LIMIT 1`,
                [blk_ticket, 'JOINBOBROS']
            );
            let discount = parseFloat(offerRows?.[0]?.discount ?? 0);
            discount = Number(discount.toFixed(2));
            
            console.log('DISCOUNT : ' , discount)

            // reward‑points reversal
            const [rewardRows] = await dbConnect.query(
                `SELECT discount AS rewardpoints
                FROM offeruse
                WHERE offercode = ?
                AND blk_ticket = ?
                LIMIT 1`,
                ["RewardPoints", blk_ticket]
            );
        
            let rewardpoints = parseFloat(rewardRows?.[0]?.rewardpoints ?? 0);
            rewardpoints = Number(rewardpoints.toFixed(2));

            let finalBal = newbal;
        

            // debit discount reversal
            if (discount > 0) {
                const discRef = `${tin}_discount_reversal`;
                const proportionalDiscount = parseFloat((discount * FractionC).toFixed(2));
               // const proportionalDiscount = parseFloat(cancelTicketResponse.proportionalDiscount) || 0;
               reversal_offer += proportionalDiscount;
                finalBal = finalBal - proportionalDiscount;
        
                await dbConnect.query(
                    `INSERT INTO t_account 
                    (bal, id, treference, tamount_dr, tamount_cr, newbal, datetime) 
                VALUES (?, ?, ?, ?, ?, ?, ?)`,
                [newbal, uid, discRef, proportionalDiscount, 0, finalBal, datetime]
                );
                console.log(`Inserted debit (discount reversal) entry for user ${uid}`);
            }

            // reward‑points reversal
            if (rewardpoints > 0) {
                const ref = `${tin}_RewardPoints_reversal`;
                const proportionalReward = parseFloat((rewardpoints * FractionC).toFixed(2));
                finalBal -= proportionalReward;
                finalBal = Number(finalBal.toFixed(2));
                reversal_offer += proportionalReward;
        
                await dbConnect.query(
                    `INSERT INTO t_account
                    (bal, id, treference, tamount_dr, tamount_cr, newbal, datetime)
                    VALUES (?, ?, ?, ?, ?, ?, ?)`,
                    [newbal, uid, ref, proportionalReward, 0, finalBal, datetime]
                );
                console.log(`Inserted reward‑points reversal for user ${uid}`);
            }
            
            
            //const proportionalReward = parseFloat(cancelTicketResponse.proportionalReward) || 0;
            console.log('The reversal points are:',reversal_offer)

        

            // update ulogin balance
            await dbConnect.query(
            `UPDATE ulogin 
               SET ubal = ? 
             WHERE uid = ?`,
            [finalBal, uid]
            );
            console.log(`Updated ulogin.ubal to ${finalBal} for user ${uid}`);
            
            
            const emailResult = await ticketCancellationEmailModel(pemail, seatsToCancel, tin, parseFloat((finalBal - ubal).toFixed(2)));
    //console.log(emailResult);
    
    if (!emailResult) {
      return res.status(500).json({ error: 'Some error in sending cancellation email' });
    }
            
            return res.status(200).json({
            refundAmount:  parseFloat((finalBal - ubal).toFixed(2)),
            availableRewardPoints: finalBal, // using same value as refundAmt
            cancelTicketResponse,
            reversal_Offer: reversal_offer
        });

    } else {
        // guest: credit net refund only
        const [offerRows] = await dbConnect.query(
            `SELECT discount 
               FROM offeruse 
              WHERE blk_ticket = ? 
              LIMIT 1`,
            [blk_ticket]
        );
        
        //refundAmt -= discount;
        const proportionalDiscount = parseFloat((discount * FractionC).toFixed(2));
            refundAmt -=   proportionalDiscount;

        // Insert guest credit entry
        await dbConnect.query(
          `INSERT INTO t_account
             (bal, id, treference, tamount_dr, tamount_cr, newbal, datetime)
           VALUES (?, ?, ?, ?, ?, ?, ?)`,
          [ubal, pmobile, cancelRef, 0, refundAmt, refundAmt, datetime]
        );
        console.log(`Inserted guest refund entry for mobile ${pmobile}`);
        
        const emailResult = await ticketCancellationEmailModel(pemail, seatsToCancel, tin, refundAmt);
    //console.log(emailResult);
    
    if (!emailResult) {
      return res.status(500).json({ error: 'Some error in sending cancellation email' });
    }
        
        
      return res.status(200).json({
            refundAmount: refundAmt,
            availableRewardPoints: "NA", // using same value as refundAmt
            cancelTicketResponse
        });
    }
    
    
    
    
}

    
    if (!cancelTicketResponse) {
      return res.status(404).json({ error: 'Some error in cancelling ticket' });
    }
   // return res.status(200).json({ cancelTicketResponse });
  } catch (error) {
    console.error('Error details:', error);
    if (error.isSeatSellerError) {
      console.log(error.message);
      res.status(error.status || 500).json({
        success: false,
        message: error.message,
      });
    } else {
      res.status(500).json({
        success: false,
        message: 'Server error occurred while processing ticket booking',
        ...(process.env.NODE_ENV === 'development' && { error: error.message })
      });
    }
  }
};

