const blockTicketModel = require("../model/blockTicketModel.js");
const dbConnect = require('../configs/dbConnection.js');

function formatBdat(date = new Date()) {
  const pad = n => String(n).padStart(2, '0');
  const year = date.getFullYear();
  const month = pad(date.getMonth() + 1);
  const day = pad(date.getDate());
  const hours = pad(date.getHours());
  const minutes = pad(date.getMinutes());
  const seconds = pad(date.getSeconds());
  const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
}


function randomNum(n = 5) {
  const min = 10 ** (n - 1);
  const max = 10 ** n - 1;
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

exports.blockTicket = async (req, res) => {
  try {
    const {
        //uId,
        //availableTripId,
        boardingPointId,
        droppingPointId,
        //dateOfJourney,
        departureTime,
        arrivalTime,
        //source,
        //destination,
        inventoryItems // This should be an array
    } = req.body;
    
    console.log(req.body);
    // console.log(JSON.stringify(req.body, null, 2));
    //////////////////////////////////////////////////////////////////
    const {
      busId : availableTripId,
      date : dateOfJourney,
      source,
      destination
    } = req.session.bus_booking;
    
    console.log("session data: ", availableTripId, dateOfJourney, source, destination);
    
    console.log("1");
    if (!availableTripId || !dateOfJourney) {
      return res.status(400).json({ message: 'Invalid booking state' });
    }
    console.log("2");
    const uId = req.session.user?.uId ?? inventoryItems[0]?.passenger?.[0]?.mobile;

    if (!uId) {
        return res.status(400).json({
        success: false,
        message: 'Invalid passenger data: mobile number not found'
        });
    }
    console.log("3");
    console.log("uId: ",uId)
    const loginUser = uId.startsWith('1');
    
    
    const ubal = req.session.user?.uId ?? "na";
    
    // let finalBal = 'na';
    //  if(loginUser){
    //       const [userRows] = await dbConnect.query(
    //       `SELECT 
    //           ubal
    //       FROM ulogin
    //       WHERE uid = ?
    //       `,
    //       [uId]
    //     );
    //     if (!userRows.length) {
    //       console.warn(`No ulogin record found for uid ${uId}`);
    //       return;
    //     }
    //     const {ubal } = userRows[0];
    //     //finalBal = ubal;
    //  }
     console.log( 'testing ubal: ', ubal)
    


    // Validate required fields
    if (!availableTripId || !boardingPointId || !droppingPointId || !inventoryItems) {
      return res.status(400).json({
        success: false,
        message: 'Missing required fields: availableTripId, boardingPointId, droppingPointId, or inventoryItems'
      });
    }

    // Validate inventoryItems is an array and not empty
    if (!Array.isArray(inventoryItems) || inventoryItems.length === 0) {
      return res.status(400).json({
        success: false,
        message: 'inventoryItems must be a non-empty array'
      });
    }

    // Format bdat string
    const bdat = formatBdat();
    const di = `ID${randomNum()}`; // Fixed: Added backticks

    // Database queries with error handling
    let sourceCity, destinationCity;
    try {
      [sourceCity] = await dbConnect.query('SELECT * FROM cities WHERE sid = ?', [source]);
      [destinationCity] = await dbConnect.query('SELECT * FROM cities WHERE sid = ?', [destination]);
    } catch (dbError) {
      console.error('Database query error:', dbError);
      return res.status(500).json({
        success: false,
        message: 'Database error while fetching city information'
      });
    }

    const snamedb = sourceCity[0]?.cityname || '';
    const dnamedb = destinationCity[0]?.cityname || '';
    const ptripdb = `${snamedb}, ${dnamedb}`; // Fixed: Added backticks
    
    // Calculate total fare with validation
    const totalFare = inventoryItems.reduce((sum, item) => {
      const fare = parseFloat(item.fare) || 0;
      return sum + fare;
    }, 0);
    
    req.session.bus_booking.fare = totalFare;
    
    let rewardpoint = totalFare * 0.04;
    rewardpoint = parseFloat(rewardpoint.toFixed(2));
    
    // let uidFinal = uId?.trim();

    // if (uidFinal?.toLowerCase() === "not applicable") {
    //   // Check if inventoryItems[0] and passenger[0] exist
    //   if (inventoryItems[0]?.passenger?.[0]?.mobile) {
    //     uidFinal = inventoryItems[0].passenger[0].mobile;
    //   } else {
    //     return res.status(400).json({
    //       success: false,
    //       message: 'Invalid passenger data: mobile number not found'
    //     });
    //   }
    //   rewardpoint = 0;
    // }

    // console.log("uidFinal : ", uidFinal);

    // First block the ticket and get the blockedTicketId
    const seatSellerPayload = {
      availableTripId,
      boardingPointId,
      droppingPointId,
      source,
      destination,
      inventoryItems
    };
    
    console.log('seatSellerPayload:', seatSellerPayload);
    
    
    
    let blockedTicketId;
    try {
      blockedTicketId = await blockTicketModel.blockTicketRequest(seatSellerPayload);
      console.log("blockedTicketId", blockedTicketId);
      req.session.bus_booking.blockedTicketId = blockedTicketId;
      
      
    } catch (blockError) {
      console.error('Block ticket error:', blockError);
      throw blockError; // Re-throw to be handled by the main catch block
    }

    console.log('Total Fares:', totalFare.toFixed(2)); 
    console.log('Inventory Items : ', inventoryItems);

    const insertQuery = `
      INSERT INTO uticket (
        uid, bdat, ptrip, pdoj, pname, psex, page, pseatno, tcost,
        fare, pmobile, pemail, dept_tim, arr_tim, tic_id,
        blk_ticket, tin_ticket, comm_discount, book_charge
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    `; // Fixed: Added backticks

    // Arrays to collect passenger info
    const passengerNames = [];
    const passengerGenders = [];
    const passengerAges = [];
    const passengerSeats = [];
    const individualFares = [];

    // Validate and process inventory items
    inventoryItems.forEach((item, index) => {
      if (!item.seatName || !item.passenger || !Array.isArray(item.passenger)) {
        throw new Error(`Invalid inventory item at index ${index}: missing seatName or passenger array`);
      }

      const { seatName, fare, passenger } = item;

      passenger.forEach((p, pIndex) => {
        if (!p.name || !p.gender || p.age === undefined) {
          throw new Error(`Invalid passenger data at inventory item ${index}, passenger ${pIndex}`);
        }
        
        const { name, gender, age } = p;
        passengerNames.push(name);
        passengerGenders.push(gender);
        passengerAges.push(age);
        passengerSeats.push(seatName);
        individualFares.push(fare || 0);
      });
    });

   // const DEFAULT_JOURNEY_DATE = '2025-07-01';

    // Validate essential passenger data exists
    if (!inventoryItems[0]?.passenger?.[0]?.mobile || !inventoryItems[0]?.passenger?.[0]?.email) {
      return res.status(400).json({
        success: false,
        message: 'Missing required passenger mobile or email'
      });
    }

    // Prepare comma-separated strings
    const insertValues = [
      uId, // uid
      bdat,
      ptripdb,
      dateOfJourney,
      passengerNames.join(', '),
      passengerGenders.join(', '),
      passengerAges.join(', '),
      passengerSeats.join(', '),
      totalFare, // combined fare
      individualFares.join(', '),
      inventoryItems[0].passenger[0].mobile, // pmobile
      inventoryItems[0].passenger[0].email,  // pemail
      departureTime || 0,  // Fixed: Use actual values instead of hardcoded 0
      arrivalTime || 0,    // Fixed: Use actual values instead of hardcoded 0
      di,              // tic_id
      blockedTicketId, // blk_ticket
      0,               // tin_ticket
      0,               // comm_discount
      0                // book_charge
    ];

    try {
      await dbConnect.query(insertQuery, insertValues);
    } catch (dbInsertError) {
      console.error('Database insert error:', dbInsertError);
      return res.status(500).json({
        success: false,
        message: 'Database error while inserting ticket data'
      });
    }
    
    console.log("rp", rewardpoint)
    
     

    // Send the response with the generated blockedTicketId
    res.status(200).json({ 
      success: true,
      blockedTicketId, 
      totalFare, 
      rewardpoint,
      availableRewardPoint : ubal
    });

  } catch (error) {
    console.error('Block ticket error:', error);
    
    // For this route, we are forwarding SeatSeller error to frontend
    if (error.isSeatSellerError) {
      // Check if the message matches "Insufficient Balance"
      const customMessage = error.message?.toLowerCase().startsWith('error: insufficient') ?
        'Booking failed due to server error.' : error.message;
      console.log(customMessage);
      res.status(error.status || 500).json({
        success: false,
        message: customMessage,
      });
    } else {
      // Better error logging and response
      console.error('Unexpected error details:', {
        message: error.message,
        stack: error.stack,
        name: error.name
      });
      
      res.status(500).json({ 
        success: false,
        message: 'Server error occurred while processing ticket booking',
        ...(process.env.NODE_ENV === 'development' && { error: error.message })
      });
    }
  }
};