const db = require('../config/database');
const PayTR = require('../utils/paytr');

// PayTR yapılandırması - .env'den yüklenecek
const getPayTRConfig = async () => {
  try {
    const [settings] = await db.query(
      `SELECT setting_key, setting_value FROM site_settings WHERE setting_key IN (?, ?, ?, ?, ?)`,
      ['paytr_merchant_id', 'paytr_merchant_key', 'paytr_merchant_salt', 'paytr_test_mode', 'currency_code']
    );

    const config = {};
    settings.forEach(s => {
      config[s.setting_key] = s.setting_value;
    });

    return {
      merchant_id: config.paytr_merchant_id || process.env.PAYTR_MERCHANT_ID,
      merchant_key: config.paytr_merchant_key || process.env.PAYTR_MERCHANT_KEY,
      merchant_salt: config.paytr_merchant_salt || process.env.PAYTR_MERCHANT_SALT,
      test_mode: config.paytr_test_mode === '1',
      currency: config.currency_code || 'EUR',
      success_url: process.env.PAYTR_SUCCESS_URL || 'http://localhost:5173/payment/success',
      fail_url: process.env.PAYTR_FAIL_URL || 'http://localhost:5173/payment/fail'
    };
  } catch (error) {
    console.error('PayTR config error:', error);
    throw new Error('PayTR yapılandırması yüklenemedi');
  }
};

// Sipariş numarası oluştur
const generateOrderNumber = () => {
  const timestamp = Date.now();
  const random = Math.floor(Math.random() * 10000);
  return `ORD-${timestamp}-${random}`;
};

// Müşteri IP adresini al
const getClientIp = (req) => {
  return req.headers['x-forwarded-for'] ||
         req.headers['x-real-ip'] ||
         req.connection.remoteAddress ||
         req.socket.remoteAddress ||
         '127.0.0.1';
};

// Fiyat hesaplama
const calculatePrice = (tour, numberOfPeople) => {
  const { adults = 0, children = 0, infants = 0 } = numberOfPeople;

  if (!tour.pricing) {
    return {
      error: 'Tur fiyat bilgisi bulunamadı',
      total: 0
    };
  }

  let roomPrice = 0;
  let roomType = '';

  // Oda tipini belirle
  if (adults === 1) {
    roomPrice = tour.pricing.single_room || tour.pricing.double_room || 0;
    roomType = 'single';
  } else if (adults === 2) {
    roomPrice = tour.pricing.double_room || 0;
    roomType = 'double';
  } else if (adults === 3) {
    roomPrice = tour.pricing.triple_room || tour.pricing.double_room || 0;
    roomType = 'triple';
  } else if (adults === 4) {
    roomPrice = tour.pricing.triple_room || tour.pricing.double_room || 0;
    roomType = 'quad';
  } else {
    return {
      error: 'Geçersiz yetişkin sayısı',
      total: 0
    };
  }

  const adultTotal = adults * roomPrice;
  const childTotal = children * (tour.pricing.child_6_12 || 0);
  const infantTotal = infants * (tour.pricing.baby_0_2 || 0);
  const total = adultTotal + childTotal + infantTotal;

  return {
    roomType,
    roomPrice,
    adultTotal,
    childTotal,
    infantTotal,
    total,
    breakdown: {
      adults: { count: adults, price: roomPrice, total: adultTotal },
      children: { count: children, price: tour.pricing.child_6_12 || 0, total: childTotal },
      infants: { count: infants, price: tour.pricing.baby_0_2 || 0, total: infantTotal }
    }
  };
};

/**
 * Rezervasyon oluştur ve PayTR ödeme başlat
 */
exports.createReservation = async (req, res) => {
  const connection = await db.getConnection();

  try {
    await connection.beginTransaction();

    const {
      tour_id,
      tour_date,
      number_of_people,
      customer_name,
      customer_email,
      customer_phone,
      customer_address,
      country_code,
      special_requests
    } = req.body;

    // Validasyon
    if (!tour_id || !number_of_people || !customer_name || !customer_email || !customer_phone || !customer_address) {
      await connection.rollback();
      return res.status(400).json({ message: 'Eksik bilgi. Lütfen tüm alanları doldurun.' });
    }

    const { adults = 0, children = 0, infants = 0 } = number_of_people;
    const totalPeople = adults + children + infants;

    // Kişi sayısı kontrolleri
    if (adults < 1 || adults > 4) {
      await connection.rollback();
      return res.status(400).json({ message: 'Yetişkin sayısı 1-4 arasında olmalıdır' });
    }
    if (children < 0 || children > 6) {
      await connection.rollback();
      return res.status(400).json({ message: 'Çocuk sayısı 0-6 arasında olmalıdır' });
    }
    if (totalPeople > 15) {
      await connection.rollback();
      return res.status(400).json({ message: 'Toplam kişi sayısı 15\'i geçemez' });
    }

    // Turu kontrol et
    const [tours] = await connection.query(
      `SELECT t.*,
        IFNULL(t.max_people, 40) - IFNULL(t.current_bookings, 0) as available_capacity
      FROM tours t
      WHERE t.id = ? AND t.status = 'active'`,
      [tour_id]
    );

    if (tours.length === 0) {
      await connection.rollback();
      return res.status(404).json({ message: 'Tur bulunamadı veya aktif değil' });
    }

    const tour = tours[0];

    // Pricing JSON'ı parse et
    if (tour.pricing && typeof tour.pricing === 'string') {
      try {
        tour.pricing = JSON.parse(tour.pricing);
      } catch (e) {
        console.error('Pricing parse error:', e);
        tour.pricing = {};
      }
    } else if (!tour.pricing) {
      tour.pricing = {};
    }

    // Kontenjan kontrolü
    if (tour.available_capacity < totalPeople) {
      await connection.rollback();
      return res.status(400).json({
        message: `Yeterli kontenjan yok. Kalan kontenjan: ${tour.available_capacity} kişi`
      });
    }

    // Fiyat hesapla
    const priceCalc = calculatePrice(tour, number_of_people);
    if (priceCalc.error) {
      await connection.rollback();
      return res.status(400).json({ message: priceCalc.error });
    }

    const total_amount = priceCalc.total;

    // Sipariş numarası oluştur
    const order_number = generateOrderNumber();

    // Müşteri oluştur veya bul
    let customer_id = null;
    const [existingCustomers] = await connection.query(
      'SELECT id FROM customers WHERE email = ?',
      [customer_email]
    );

    if (existingCustomers.length > 0) {
      customer_id = existingCustomers[0].id;
      // Müşteri bilgilerini güncelle
      await connection.query(
        'UPDATE customers SET full_name = ?, phone = ? WHERE id = ?',
        [customer_name, `${country_code}${customer_phone}`, customer_id]
      );
    } else {
      const [customerResult] = await connection.query(
        'INSERT INTO customers (full_name, email, phone) VALUES (?, ?, ?)',
        [customer_name, customer_email, `${country_code}${customer_phone}`]
      );
      customer_id = customerResult.insertId;
    }

    // IP adresi
    const user_ip = getClientIp(req);

    // Sepet içeriği oluştur
    const basketItems = [];
    if (priceCalc.breakdown.adults.count > 0) {
      basketItems.push({
        name: `${tour.title} - Yetişkin`,
        price: priceCalc.breakdown.adults.price,
        quantity: priceCalc.breakdown.adults.count
      });
    }
    if (priceCalc.breakdown.children.count > 0) {
      basketItems.push({
        name: `${tour.title} - Çocuk`,
        price: priceCalc.breakdown.children.price,
        quantity: priceCalc.breakdown.children.count
      });
    }
    if (priceCalc.breakdown.infants.count > 0) {
      basketItems.push({
        name: `${tour.title} - Bebek`,
        price: priceCalc.breakdown.infants.price,
        quantity: priceCalc.breakdown.infants.count
      });
    }

    const user_basket = PayTR.createUserBasket(basketItems);

    // Siparişi veritabanına kaydet
    const [orderResult] = await connection.query(
      `INSERT INTO orders (
        order_number, customer_id, tour_id, tour_date, number_of_people,
        total_amount, customer_name, customer_email, customer_phone, customer_address,
        special_requests, payment_status, booking_status, room_type,
        ip_address, user_basket
      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', 'pending', ?, ?, ?)`,
      [
        order_number,
        customer_id,
        tour_id,
        tour_date || tour.tour_date,
        JSON.stringify(number_of_people),
        total_amount,
        customer_name,
        customer_email,
        `${country_code}${customer_phone}`,
        customer_address,
        special_requests || null,
        priceCalc.roomType,
        user_ip,
        user_basket
      ]
    );

    const order_id = orderResult.insertId;

    // PayTR ödeme başlat
    const paytrConfig = await getPayTRConfig();
    const paytr = new PayTR(paytrConfig);

    // EUR ise TL'ye çevir (dinamik kur ile)
    let payment_amount_kurus = PayTR.amountToKurus(total_amount);
    let currency = paytrConfig.currency;

    if (currency === 'EUR') {
      // TODO: Gerçek kur bilgisi alınabilir
      const eurToTryRate = 35.50; // Örnek kur
      payment_amount_kurus = PayTR.amountToKurus(total_amount * eurToTryRate);
      currency = 'TL';
    }

    const paymentData = {
      merchant_oid: order_number,
      email: customer_email,
      payment_amount: payment_amount_kurus,
      user_basket: user_basket,
      user_name: customer_name,
      user_address: customer_address || 'Türkiye',
      user_phone: customer_phone,
      user_ip: user_ip,
      currency: currency,
      no_installment: 0,
      max_installment: 0,
      debug_on: paytrConfig.test_mode ? 1 : 0,
      lang: 'tr'
    };

    const paymentResult = await paytr.createPaymentToken(paymentData);

    if (!paymentResult.success) {
      await connection.rollback();
      return res.status(500).json({
        message: 'Ödeme başlatılamadı: ' + paymentResult.error
      });
    }

    // PayTR token'ı siparişe kaydet
    await connection.query(
      'UPDATE orders SET paytr_token = ?, paytr_iframe_token = ? WHERE id = ?',
      [paymentResult.token, paymentResult.iframeUrl, order_id]
    );

    await connection.commit();

    res.status(201).json({
      success: true,
      message: 'Rezervasyon oluşturuldu',
      order: {
        id: order_id,
        order_number: order_number,
        total_amount: total_amount,
        currency: paytrConfig.currency
      },
      payment: {
        token: paymentResult.token,
        iframeUrl: paymentResult.iframeUrl
      }
    });

  } catch (error) {
    await connection.rollback();
    console.error('Reservation error:', error);
    res.status(500).json({
      message: 'Rezervasyon oluşturulamadı',
      error: error.message
    });
  } finally {
    connection.release();
  }
};

/**
 * PayTR Callback - Ödeme sonucu bildirim
 */
exports.paytrCallback = async (req, res) => {
  try {
    const {
      merchant_oid,
      status,
      total_amount,
      hash,
      failed_reason_code,
      failed_reason_msg,
      test_mode,
      payment_type,
      currency,
      payment_amount
    } = req.body;

    console.log('PayTR Callback received:', { merchant_oid, status });

    // PayTR config
    const paytrConfig = await getPayTRConfig();
    const paytr = new PayTR(paytrConfig);

    // Hash doğrulama
    const verification = paytr.verifyCallback({ merchant_oid, status, total_amount, hash });

    if (!verification.success) {
      console.error('PayTR Hash verification failed');
      return res.send('OK'); // PayTR'a her durumda OK dönmek gerekiyor
    }

    // Siparişi bul
    const [orders] = await db.query(
      'SELECT * FROM orders WHERE order_number = ?',
      [merchant_oid]
    );

    if (orders.length === 0) {
      console.error('Order not found:', merchant_oid);
      return res.send('OK');
    }

    const order = orders[0];

    // ÖNEMLİ: Sipariş zaten onaylandıysa tekrar işlem yapma
    if (order.payment_status === 'paid' && status === 'success') {
      console.log('⚠️ Order already paid:', merchant_oid);
      return res.send('OK');
    }

    // Ödeme transaction kaydı oluştur
    await db.query(
      `INSERT INTO payment_transactions
      (order_id, transaction_type, amount, currency, paytr_merchant_oid, paytr_payment_status, paytr_response, ip_address)
      VALUES (?, 'payment', ?, ?, ?, ?, ?, ?)`,
      [
        order.id,
        total_amount / 100, // Kuruştan çevir
        currency,
        merchant_oid,
        status,
        JSON.stringify(req.body),
        getClientIp(req)
      ]
    );

    // Sipariş durumunu güncelle
    if (status === 'success') {
      await db.query(
        `UPDATE orders
        SET payment_status = 'paid',
            booking_status = 'confirmed',
            payment_response = ?
        WHERE id = ?`,
        [JSON.stringify(req.body), order.id]
      );

      // TODO: Müşteriye email gönder
      console.log('Payment successful for order:', merchant_oid);
    } else {
      await db.query(
        `UPDATE orders
        SET payment_status = 'failed',
            booking_status = 'cancelled',
            payment_response = ?
        WHERE id = ?`,
        [JSON.stringify(req.body), order.id]
      );

      console.log('Payment failed for order:', merchant_oid, failed_reason_msg);
    }

    res.send('OK');

  } catch (error) {
    console.error('PayTR Callback error:', error);
    res.send('OK'); // PayTR'a her durumda OK dönmek gerekiyor
  }
};

/**
 * Tüm rezervasyonları listele (Admin)
 */
exports.getAllReservations = async (req, res) => {
  try {
    const { booking_status, payment_status, tour_id, limit = 100, offset = 0 } = req.query;

    let query = `
      SELECT
        o.*,
        t.title as tour_title,
        t.route as tour_route,
        t.duration as tour_duration,
        c.full_name as customer_full_name
      FROM orders o
      LEFT JOIN tours t ON o.tour_id = t.id
      LEFT JOIN customers c ON o.customer_id = c.id
      WHERE 1=1
    `;
    const params = [];

    if (booking_status) {
      query += ' AND o.booking_status = ?';
      params.push(booking_status);
    }

    if (payment_status) {
      query += ' AND o.payment_status = ?';
      params.push(payment_status);
    }

    if (tour_id) {
      query += ' AND o.tour_id = ?';
      params.push(tour_id);
    }

    query += ' ORDER BY o.created_at DESC LIMIT ? OFFSET ?';
    params.push(parseInt(limit), parseInt(offset));

    const [orders] = await db.query(query, params);

    // Toplam sayfa sayısı
    const [countResult] = await db.query(
      'SELECT COUNT(*) as total FROM orders WHERE 1=1' +
      (booking_status ? ' AND booking_status = ?' : '') +
      (payment_status ? ' AND payment_status = ?' : ''),
      params.filter((_, i) => i < params.length - 2)
    );

    res.json({
      data: orders,
      total: countResult[0].total,
      limit: parseInt(limit),
      offset: parseInt(offset)
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

/**
 * Rezervasyon detayı (Admin)
 */
exports.getReservationById = async (req, res) => {
  try {
    const [orders] = await db.query(
      `SELECT o.*,
        t.title as tour_title,
        t.description as tour_description,
        t.route as tour_route,
        t.duration as tour_duration,
        c.full_name as customer_full_name,
        c.email as customer_full_email,
        c.phone as customer_full_phone
      FROM orders o
      LEFT JOIN tours t ON o.tour_id = t.id
      LEFT JOIN customers c ON o.customer_id = c.id
      WHERE o.id = ?`,
      [req.params.id]
    );

    if (orders.length === 0) {
      return res.status(404).json({ message: 'Rezervasyon bulunamadı' });
    }

    // İlgili ödemeleri de getir
    const [transactions] = await db.query(
      'SELECT * FROM payment_transactions WHERE order_id = ? ORDER BY created_at DESC',
      [req.params.id]
    );

    res.json({
      ...orders[0],
      transactions
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

/**
 * Rezervasyon durumunu güncelle (Admin)
 */
exports.updateReservationStatus = async (req, res) => {
  try {
    const { booking_status, payment_status, admin_notes } = req.body;

    const updateFields = [];
    const params = [];

    if (booking_status) {
      updateFields.push('booking_status = ?');
      params.push(booking_status);
    }

    if (payment_status) {
      updateFields.push('payment_status = ?');
      params.push(payment_status);
    }

    if (admin_notes !== undefined) {
      updateFields.push('admin_notes = ?');
      params.push(admin_notes);
    }

    if (updateFields.length === 0) {
      return res.status(400).json({ message: 'Güncellenecek alan bulunamadı' });
    }

    params.push(req.params.id);

    const [result] = await db.query(
      `UPDATE orders SET ${updateFields.join(', ')} WHERE id = ?`,
      params
    );

    if (result.affectedRows === 0) {
      return res.status(404).json({ message: 'Rezervasyon bulunamadı' });
    }

    res.json({ message: 'Rezervasyon durumu güncellendi' });
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};

/**
 * Kontenjan kontrolü
 */
exports.checkAvailability = async (req, res) => {
  try {
    const { tour_id, number_of_people } = req.query;

    if (!tour_id || !number_of_people) {
      return res.status(400).json({ message: 'Tur ID ve kişi sayısı gerekli' });
    }

    const peopleCount = JSON.parse(number_of_people);
    const totalPeople = (peopleCount.adults || 0) + (peopleCount.children || 0) + (peopleCount.infants || 0);

    const [tours] = await db.query(
      `SELECT
        id, title,
        IFNULL(max_people, 40) as max_capacity,
        IFNULL(current_bookings, 0) as current_bookings,
        IFNULL(max_people, 40) - IFNULL(current_bookings, 0) as available_seats
      FROM tours
      WHERE id = ? AND status = 'active'`,
      [tour_id]
    );

    if (tours.length === 0) {
      return res.status(404).json({ message: 'Tur bulunamadı' });
    }

    const tour = tours[0];
    const isAvailable = tour.available_seats >= totalPeople;

    res.json({
      available: isAvailable,
      max_capacity: tour.max_capacity,
      current_bookings: tour.current_bookings,
      available_seats: tour.available_seats,
      requested_seats: totalPeople,
      message: isAvailable
        ? 'Kontenjan müsait'
        : `Yeterli kontenjan yok. Kalan: ${tour.available_seats} kişi`
    });

  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Sunucu hatası' });
  }
};
