<?php
/**
 * OTA Integration Service
 * Handles Airbnb and Booking.com API integration
 */

class OTAIntegrationService {
    private $db;
    private $config;

    public function __construct($db, $config) {
        $this->db = $db;
        $this->config = $config;
    }

    /**
     * Sync bookings from Airbnb
     */
    public function syncAirbnbBookings($property_id) {
        try {
            $stmt = $this->db->prepare("
                SELECT ota_connection_id FROM ota_connections 
                WHERE property_id = ? AND platform = 'airbnb'
            ");
            $stmt->execute([$property_id]);
            $connection = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$connection) {
                return ['success' => false, 'message' => 'Airbnb not connected for this property'];
            }

            // Get Airbnb connection details
            $airbnb_api_key = $this->config['airbnb']['api_key'] ?? null;
            if (!$airbnb_api_key) {
                return ['success' => false, 'message' => 'Airbnb API key not configured'];
            }

            // Fetch bookings from Airbnb
            $airbnb_bookings = $this->fetchAirbnbBookings($property_id, $airbnb_api_key);

            if (!$airbnb_bookings['success']) {
                return $airbnb_bookings;
            }

            // Process and import bookings
            $imported = 0;
            foreach ($airbnb_bookings['bookings'] as $booking_data) {
                if ($this->importBookingFromOTA($property_id, $booking_data, 'airbnb')) {
                    $imported++;
                }
            }

            // Log sync
            $this->logOTASync($property_id, 'airbnb', 'success', "Imported $imported bookings");

            return [
                'success' => true,
                'message' => "Synced $imported bookings from Airbnb",
                'imported' => $imported
            ];

        } catch (Exception $e) {
            error_log('Airbnb sync error: ' . $e->getMessage());
            $this->logOTASync($property_id, 'airbnb', 'failed', $e->getMessage());
            return ['success' => false, 'message' => 'Error syncing Airbnb bookings'];
        }
    }

    /**
     * Sync bookings from Booking.com
     */
    public function syncBookingComBookings($property_id) {
        try {
            $stmt = $this->db->prepare("
                SELECT ota_connection_id FROM ota_connections 
                WHERE property_id = ? AND platform = 'booking'
            ");
            $stmt->execute([$property_id]);
            $connection = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$connection) {
                return ['success' => false, 'message' => 'Booking.com not connected for this property'];
            }

            $booking_api_key = $this->config['booking_com']['api_key'] ?? null;
            if (!$booking_api_key) {
                return ['success' => false, 'message' => 'Booking.com API key not configured'];
            }

            // Fetch bookings from Booking.com
            $bookings = $this->fetchBookingComBookings($property_id, $booking_api_key);

            if (!$bookings['success']) {
                return $bookings;
            }

            // Process and import bookings
            $imported = 0;
            foreach ($bookings['bookings'] as $booking_data) {
                if ($this->importBookingFromOTA($property_id, $booking_data, 'booking')) {
                    $imported++;
                }
            }

            // Log sync
            $this->logOTASync($property_id, 'booking', 'success', "Imported $imported bookings");

            return [
                'success' => true,
                'message' => "Synced $imported bookings from Booking.com",
                'imported' => $imported
            ];

        } catch (Exception $e) {
            error_log('Booking.com sync error: ' . $e->getMessage());
            $this->logOTASync($property_id, 'booking', 'failed', $e->getMessage());
            return ['success' => false, 'message' => 'Error syncing Booking.com bookings'];
        }
    }

    /**
     * Fetch bookings from Airbnb (simulation - use real API in production)
     */
    private function fetchAirbnbBookings($property_id, $api_key) {
        try {
            // In production, make actual API call to Airbnb
            // For now, return simulated data
            return [
                'success' => true,
                'bookings' => [
                    [
                        'external_id' => 'airbnb_123456',
                        'guest_name' => 'John Smith',
                        'guest_email' => 'john@example.com',
                        'phone' => '+1234567890',
                        'check_in' => date('Y-m-d', strtotime('+5 days')),
                        'check_out' => date('Y-m-d', strtotime('+10 days')),
                        'price' => 500,
                        'source' => 'airbnb',
                        'status' => 'confirmed'
                    ]
                ]
            ];

        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error fetching Airbnb bookings'];
        }
    }

    /**
     * Fetch bookings from Booking.com
     */
    private function fetchBookingComBookings($property_id, $api_key) {
        try {
            // In production, make actual API call to Booking.com
            // For now, return simulated data
            return [
                'success' => true,
                'bookings' => [
                    [
                        'external_id' => 'booking_789012',
                        'guest_name' => 'Sarah Johnson',
                        'guest_email' => 'sarah@example.com',
                        'phone' => '+1234567891',
                        'check_in' => date('Y-m-d', strtotime('+12 days')),
                        'check_out' => date('Y-m-d', strtotime('+18 days')),
                        'price' => 450,
                        'source' => 'booking',
                        'status' => 'confirmed'
                    ]
                ]
            ];

        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error fetching Booking.com bookings'];
        }
    }

    /**
     * Import booking from OTA
     */
    private function importBookingFromOTA($property_id, $booking_data, $source) {
        try {
            // Check if booking already exists
            $stmt = $this->db->prepare("
                SELECT id FROM bookings 
                WHERE property_id = ? AND external_id = ?
            ");
            $stmt->execute([$property_id, $booking_data['external_id']]);
            if ($stmt->fetch()) {
                return false; // Already imported
            }

            // Create or update guest
            $guest_id = $this->findOrCreateGuest(
                $booking_data['guest_name'],
                $booking_data['guest_email'],
                $booking_data['phone'] ?? null
            );

            // Calculate nights
            $checkin = new DateTime($booking_data['check_in']);
            $checkout = new DateTime($booking_data['check_out']);
            $nights = $checkout->diff($checkin)->days;

            // Generate booking reference
            $booking_ref = 'HV-' . strtoupper(substr(uniqid('', true), -8, 8));
            $guest_token = 'bk_' . bin2hex(random_bytes(8));

            // Create booking
            $stmt = $this->db->prepare("
                INSERT INTO bookings (
                    booking_reference, external_id, guest_id, property_id,
                    check_in, check_out, nights, price, status,
                    source, guest_token, created_at, updated_at
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
            ");

            $stmt->execute([
                $booking_ref,
                $booking_data['external_id'],
                $guest_id,
                $property_id,
                $booking_data['check_in'],
                $booking_data['check_out'],
                $nights,
                $booking_data['price'] ?? 0,
                $booking_data['status'] ?? 'confirmed',
                $source,
                $guest_token
            ]);

            // Create housekeeping task
            $this->createHousekeepingTask(
                $this->db->lastInsertId(),
                $property_id,
                $booking_data['check_in'],
                $booking_data['check_out']
            );

            return true;

        } catch (Exception $e) {
            error_log('Error importing booking: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Find or create guest
     */
    private function findOrCreateGuest($name, $email, $phone = null) {
        try {
            // Find existing guest
            $stmt = $this->db->prepare("SELECT id FROM guests WHERE email = ?");
            $stmt->execute([$email]);
            $guest = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($guest) {
                return $guest['id'];
            }

            // Create new guest
            $stmt = $this->db->prepare("
                INSERT INTO guests (name, email, phone, created_at)
                VALUES (?, ?, ?, NOW())
            ");
            $stmt->execute([$name, $email, $phone]);

            return $this->db->lastInsertId();

        } catch (Exception $e) {
            error_log('Error managing guest: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * Create housekeeping task from booking
     */
    private function createHousekeepingTask($booking_id, $property_id, $check_in, $check_out) {
        try {
            // Create cleaning task for check-in
            $stmt = $this->db->prepare("
                INSERT INTO housekeeping_tasks (
                    booking_id, property_id, task_type, scheduled_date, status, created_at
                ) VALUES (?, ?, ?, ?, 'pending', NOW())
            ");

            // Cleaning before check-in (day before)
            $clean_before = date('Y-m-d', strtotime($check_in . ' -1 day'));
            $stmt->execute([$booking_id, $property_id, 'cleaning', $clean_before]);

            // Cleaning after checkout
            $stmt->execute([$booking_id, $property_id, 'cleaning', $check_out]);

        } catch (Exception $e) {
            error_log('Error creating housekeeping task: ' . $e->getMessage());
        }
    }

    /**
     * Get OTA sync status
     */
    public function getSyncStatus($property_id) {
        try {
            $stmt = $this->db->prepare("
                SELECT platform, last_sync, status, message
                FROM ota_sync_log
                WHERE property_id = ?
                ORDER BY last_sync DESC
                LIMIT 10
            ");
            $stmt->execute([$property_id]);
            $logs = $stmt->fetchAll(PDO::FETCH_ASSOC);

            return [
                'success' => true,
                'syncs' => $logs
            ];

        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error fetching sync status'];
        }
    }

    /**
     * Log OTA sync
     */
    private function logOTASync($property_id, $platform, $status, $message) {
        try {
            $stmt = $this->db->prepare("
                INSERT INTO ota_sync_log (property_id, platform, status, message, last_sync)
                VALUES (?, ?, ?, ?, NOW())
            ");
            $stmt->execute([$property_id, $platform, $status, $message]);
        } catch (Exception $e) {
            error_log('Error logging sync: ' . $e->getMessage());
        }
    }

    /**
     * Get calendar availability
     */
    public function getCalendar($property_id, $month = null, $year = null) {
        try {
            if (!$month) $month = date('m');
            if (!$year) $year = date('Y');

            $stmt = $this->db->prepare("
                SELECT 
                    DATE(check_in) as booked_date,
                    source,
                    status
                FROM bookings
                WHERE property_id = ?
                AND YEAR(check_in) = ?
                AND MONTH(check_in) = ?
                AND status != 'cancelled'
            ");

            $stmt->execute([$property_id, $year, $month]);
            $bookings = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Create calendar
            $calendar = [];
            $days = cal_days_in_month(CAL_GREGORIAN, $month, $year);

            for ($day = 1; $day <= $days; $day++) {
                $date = sprintf('%04d-%02d-%02d', $year, $month, $day);
                $booked = false;
                $sources = [];

                foreach ($bookings as $booking) {
                    if ($booking['booked_date'] == $date) {
                        $booked = true;
                        $sources[] = $booking['source'];
                    }
                }

                $calendar[] = [
                    'date' => $date,
                    'booked' => $booked,
                    'sources' => $sources
                ];
            }

            return [
                'success' => true,
                'month' => $month,
                'year' => $year,
                'calendar' => $calendar
            ];

        } catch (Exception $e) {
            return ['success' => false, 'message' => 'Error fetching calendar'];
        }
    }
}
