<?php
session_start();
require_once 'layouts/dbconn.php';
require_once 'layouts/session.php';

header('Content-Type: application/json');

// Check authentication
if (!isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Unauthorized access']);
    exit();
}

// Check permissions
$allowed_roles = ['SUPER_ADMIN', 'HOSPITAL_ADMIN', 'CHIEF_PHARMACIST', 'PHARMACIST', 'PHARMACY_TECH'];
if (!in_array($_SESSION['role_code'], $allowed_roles)) {
    echo json_encode(['success' => false, 'message' => 'Insufficient permissions']);
    exit();
}

try {
    // Start transaction
    $conn->begin_transaction();
    
    // Get form data
    $patient_type = strtoupper($_POST['patient_type'] ?? '');
    $dispensed_by = (int)$_POST['dispensed_by'];
    $payment_method = $_POST['payment_method'] ?? '';
    $insurance_provider_id = !empty($_POST['insurance_provider_id']) ? (int)$_POST['insurance_provider_id'] : null;
    $notes = $_POST['notes'] ?? '';
    
    // Validate required fields
    if (empty($patient_type) || empty($payment_method)) {
        throw new Exception('Patient type and payment method are required');
    }
    
    // Validate medications
    if (empty($_POST['medication']) || !is_array($_POST['medication'])) {
        throw new Exception('At least one medication is required');
    }
    
    // Calculate total amount
    $total_amount = 0;
    $quantities = $_POST['quantity'] ?? [];
    $unit_prices = $_POST['unit_price'] ?? [];
    
    foreach ($_POST['medication'] as $index => $inventory_id) {
        $quantity = (int)($quantities[$index] ?? 0);
        $unit_price = (float)($unit_prices[$index] ?? 0);
        $total_amount += ($quantity * $unit_price);
    }
    
    // Get patient details based on type
    $patient_id = null;
    $patient_name = '';
    $patient_phone = '';
    $visit_id = null;
    $prescription_id = null;
    
    switch ($patient_type) {
        case 'REGISTERED':
            // Get patient_id (required for registered patients)
            $patient_id = !empty($_POST['patient_id']) ? (int)$_POST['patient_id'] : null;
            if (!$patient_id) {
                throw new Exception('Patient selection is required for registered patients');
            }
            
            // Get patient details
            $patient_sql = "SELECT pt.patient_id, u.full_name, u.phone_primary
                           FROM patients pt
                           INNER JOIN users u ON pt.user_id = u.user_id
                           WHERE pt.patient_id = ?";
            $stmt = $conn->prepare($patient_sql);
            $stmt->bind_param('i', $patient_id);
            $stmt->execute();
            $result = $stmt->get_result();
            
            if ($result->num_rows === 0) {
                throw new Exception('Patient not found');
            }
            
            $patient_data = $result->fetch_assoc();
            $patient_name = $patient_data['full_name'];
            $patient_phone = $patient_data['phone_primary'];
            
            // Get prescription_id if selected (optional)
            $prescription_id = !empty($_POST['selected_prescription_id']) ? (int)$_POST['selected_prescription_id'] : null;
            
            // If prescription is selected, get visit_id
            if ($prescription_id) {
                $visit_sql = "SELECT visit_id FROM prescriptions WHERE prescription_id = ?";
                $visit_stmt = $conn->prepare($visit_sql);
                $visit_stmt->bind_param('i', $prescription_id);
                $visit_stmt->execute();
                $visit_result = $visit_stmt->get_result();
                if ($visit_row = $visit_result->fetch_assoc()) {
                    $visit_id = $visit_row['visit_id'];
                }
            }
            break;
            
        case 'WALK_IN':
            $patient_name = $_POST['walk_in_name'] ?? '';
            $patient_phone = $_POST['walk_in_phone'] ?? '';
            if (empty($patient_name)) {
                throw new Exception('Patient name is required for walk-in patients');
            }
            break;
            
        case 'REFERRED':
            $patient_name = $_POST['referred_name'] ?? '';
            $patient_phone = $_POST['referred_phone'] ?? '';
            if (empty($patient_name)) {
                throw new Exception('Patient name is required for referred patients');
            }
            break;
            
        default:
            throw new Exception('Invalid patient type');
    }
    
    // Determine payment status based on payment method
    $payment_status = 'PAID';
    $amount_paid = $total_amount;
    
    if ($payment_method === 'INSURANCE') {
        $payment_status = 'PENDING';
        $amount_paid = 0;
        if (!$insurance_provider_id) {
            throw new Exception('Insurance provider is required for insurance payments');
        }
    }
    
    // Handle prescription image upload
    $prescription_image_path = null;
    if (isset($_FILES['prescription_image']) && $_FILES['prescription_image']['error'] === UPLOAD_ERR_OK) {
        $upload_dir = 'uploads/prescriptions/';
        if (!is_dir($upload_dir)) {
            mkdir($upload_dir, 0755, true);
        }
        
        $file_extension = pathinfo($_FILES['prescription_image']['name'], PATHINFO_EXTENSION);
        $file_name = 'prescription_' . time() . '_' . uniqid() . '.' . $file_extension;
        $prescription_image_path = $upload_dir . $file_name;
        
        if (!move_uploaded_file($_FILES['prescription_image']['tmp_name'], $prescription_image_path)) {
            throw new Exception('Failed to upload prescription image');
        }
    }
    
    // Generate dispensing number
    $dispensing_number = null;
    $num_sql = "SELECT GenerateDispensingNumber() as dispensing_number";
    $num_result = $conn->query($num_sql);
    if ($num_result && $row = $num_result->fetch_assoc()) {
        $dispensing_number = $row['dispensing_number'];
    }
    
    if (!$dispensing_number) {
        throw new Exception('Failed to generate dispensing number');
    }
    
    // Insert into pharmacy_dispensing
    $insert_dispensing = "INSERT INTO pharmacy_dispensing (
        dispensing_number, prescription_id, patient_id, patient_type, visit_id,
        patient_name, patient_phone, dispensed_by, total_amount, amount_paid,
        payment_method, payment_status, insurance_provider_id, prescription_image, notes
    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
    
    $stmt = $conn->prepare($insert_dispensing);
    $stmt->bind_param(
        'siisissiiddisss',
        $dispensing_number,
        $prescription_id,
        $patient_id,
        $patient_type,
        $visit_id,
        $patient_name,
        $patient_phone,
        $dispensed_by,
        $total_amount,
        $amount_paid,
        $payment_method,
        $payment_status,
        $insurance_provider_id,
        $prescription_image_path,
        $notes
    );
    
    if (!$stmt->execute()) {
        throw new Exception('Failed to create dispensing record: ' . $stmt->error);
    }
    
    $dispensing_id = $conn->insert_id;
    
    // Insert dispensing items
    $insert_item = "INSERT INTO pharmacy_dispensing_items (
        dispensing_id, inventory_id, item_name, quantity, unit_price, dosage_instructions
    ) VALUES (?, ?, ?, ?, ?, ?)";
    
    $stmt = $conn->prepare($insert_item);
    
    foreach ($_POST['medication'] as $index => $inventory_id) {
        $inventory_id = (int)$inventory_id;
        $quantity = (int)($quantities[$index] ?? 0);
        $unit_price = (float)($unit_prices[$index] ?? 0);
        $dosage_instructions = $_POST['dosage_instructions'][$index] ?? '';
        
        // Get item name
        $item_sql = "SELECT item_name FROM pharmacy_inventory WHERE inventory_id = ?";
        $item_stmt = $conn->prepare($item_sql);
        $item_stmt->bind_param('i', $inventory_id);
        $item_stmt->execute();
        $item_result = $item_stmt->get_result();
        $item_data = $item_result->fetch_assoc();
        $item_name = $item_data['item_name'] ?? '';
        
        $stmt->bind_param(
            'iisids',
            $dispensing_id,
            $inventory_id,
            $item_name,
            $quantity,
            $unit_price,
            $dosage_instructions
        );
        
        if (!$stmt->execute()) {
            throw new Exception('Failed to add dispensing item: ' . $stmt->error);
        }
    }
    
    // Update prescription as dispensed if applicable
    if ($prescription_id) {
        $update_pres = "UPDATE prescriptions SET 
                       dispensed = 1, 
                       dispensed_by = ?, 
                       dispensed_at = NOW(),
                       status = 'COMPLETED'
                       WHERE prescription_id = ?";
        $stmt = $conn->prepare($update_pres);
        $stmt->bind_param('ii', $dispensed_by, $prescription_id);
        $stmt->execute();
    }
    
    // Log activity
    $log_sql = "INSERT INTO activity_log (user_id, action, module, record_id, record_type, new_values, ip_address, user_agent)
                VALUES (?, 'CREATE', 'PHARMACY_DISPENSING', ?, 'DISPENSING', ?, ?, ?)";
    $log_stmt = $conn->prepare($log_sql);
    $log_data = json_encode([
        'dispensing_number' => $dispensing_number,
        'patient_type' => $patient_type,
        'patient_name' => $patient_name,
        'total_amount' => $total_amount,
        'payment_method' => $payment_method,
        'payment_status' => $payment_status
    ]);
    $ip_address = $_SERVER['REMOTE_ADDR'];
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
    $log_stmt->bind_param('iisss', $_SESSION['user_id'], $dispensing_id, $log_data, $ip_address, $user_agent);
    $log_stmt->execute();
    
    // Commit transaction
    $conn->commit();
    
    // Prepare response
    $response = [
        'success' => true,
        'message' => 'Dispensing processed successfully',
        'dispensing_id' => $dispensing_id,
        'dispensing_number' => $dispensing_number,
        'payment_status' => $payment_status,
        'total_amount' => $total_amount
    ];
    
    // For insurance payments, indicate that invoice and dispensing note will be generated
    if ($payment_method === 'INSURANCE') {
        $response['message'] = 'Dispensing processed successfully. Payment marked as PENDING for insurance reconciliation.';
        $response['generate_documents'] = true;
    }
    
    echo json_encode($response);
    
} catch (Exception $e) {
    // Rollback on error
    $conn->rollback();
    
    echo json_encode([
        'success' => false,
        'message' => $e->getMessage()
    ]);
}

$conn->close();
?>