<?php
header('Content-Type: application/json');
include 'layouts/dbconn.php';
include 'claim_validations.php';
session_start();

if (!isset($_SESSION['user_id'])) {
    http_response_code(401);
    echo json_encode(['error' => 'Unauthorized']);
    exit;
}

try {
    $data = json_decode(file_get_contents('php://input'), true);
    error_log("Received data: " . print_r($data, true));

    if (!$data || !isset($data['claims']) || !is_array($data['claims'])) {
        throw new Exception('Invalid data received');
    }

    // Validate diagnoses
    if (!isset($data['diagnoses']) || !is_array($data['diagnoses']) || empty($data['diagnoses'])) {
        throw new Exception('At least one diagnosis is required');
    }

    // Verify at least one primary diagnosis
    $hasPrimaryDiagnosis = false;
    foreach ($data['diagnoses'] as $diagnosis) {
        if ($diagnosis['primary']) {
            $hasPrimaryDiagnosis = true;
            break;
        }
    }

    if (!$hasPrimaryDiagnosis) {
        throw new Exception('A primary diagnosis must be selected');
    }

    $conn->begin_transaction();

    // Check if this is an existing claim
    $check_sql = "SELECT COUNT(*) as count FROM bills WHERE claim_no = ?";
    $check_stmt = $conn->prepare($check_sql);
    $check_stmt->bind_param("s", $data['claim_no']);
    $check_stmt->execute();
    $result = $check_stmt->get_result();
    $is_existing_claim = $result->fetch_assoc()['count'] > 0;

    // Save or update diagnoses
    if ($is_existing_claim) {
        // For existing claims, delete existing diagnoses first (optional, depends on your business logic)
        $delete_diag_sql = "DELETE FROM claim_diagnoses WHERE claim_no = ?";
        $delete_diag_stmt = $conn->prepare($delete_diag_sql);
        $delete_diag_stmt->bind_param("s", $data['claim_no']);
        $delete_diag_stmt->execute();
    }

    // Save diagnoses for this claim
    foreach ($data['diagnoses'] as $diagnosis) {
        $sql = "INSERT INTO claim_diagnoses (
            claim_no,
            icd10_id,
            primary_diagnosis,
            created_by
        ) VALUES (?, ?, ?, ?)";

        $stmt = $conn->prepare($sql);
        $primary = $diagnosis['primary'] ? 1 : 0;
        $stmt->bind_param(
            "siis",
            $data['claim_no'],
            $diagnosis['id'],
            $primary,
            $_SESSION['user_id']
        );

        if (!$stmt->execute()) {
            throw new Exception("Failed to save diagnosis: " . $stmt->error);
        }
    }

    // Save claims with policy validations
    foreach ($data['claims'] as $claim) {
        // Check if this claim line already exists
        $check_line_sql = "SELECT COUNT(*) as count FROM bills 
                          WHERE claim_no = ? AND service = ? AND provider = ?";
        $check_line_stmt = $conn->prepare($check_line_sql);
        $check_line_stmt->bind_param("sii", 
            $data['claim_no'], 
            $claim['description'], 
            $data['provider']
        );
        $check_line_stmt->execute();
        $result = $check_line_stmt->get_result();
        $line_exists = $result->fetch_assoc()['count'] > 0;

        // Skip existing claim lines
        if ($line_exists) {
            continue;
        }

        // Check provider restrictions
        $sql = "SELECT * FROM scheme_provider_restrictions 
                WHERE corp_id = ? 
                AND benefit_code = ? 
                AND provider_id = ? 
                AND status = 'ACTIVE'";
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param('sii', 
            $data['corp_id'], 
            $claim['benefit_code'], 
            $data['provider']
        );
        $stmt->execute();
        $restriction = $stmt->get_result()->fetch_assoc();

        if ($restriction && $restriction['restriction_type'] === 'NOT_ALLOWED') {
            throw new Exception("Provider is not authorized for this benefit");
        }

        // Check copay requirements
        $sql = "SELECT * FROM scheme_copay 
                WHERE corp_id = ? 
                AND benefit_code = ? 
                AND status = 'ACTIVE'";
        
        $stmt = $conn->prepare($sql);
        $stmt->bind_param('si', $data['corp_id'], $claim['benefit_code']);
        $stmt->execute();
        $copay = $stmt->get_result()->fetch_assoc();

        $copay_amount = 0;
        if ($copay) {
            if ($copay['copay_type'] === 'PERCENTAGE') {
                $copay_amount = ($claim['amount'] * $copay['copay_value']) / 100;
            } else {
                $copay_amount = $copay['copay_value'];
            }
        }

        // Calculate payable amount
        $payable_amount = $claim['amount'] - $copay_amount;

        // Check for matching pre-auth
        $sql_preauth = "SELECT code, reserve FROM pre_authorization 
                       WHERE member_no = ? 
                       AND service = ? 
                       AND provider = ? 
                       AND authority_type = ? 
                       AND reserve > 0";
                       
        $stmt = $conn->prepare($sql_preauth);
        $stmt->bind_param("siii", 
            $data['member_no'],
            $claim['description'],
            $data['provider'],
            $claim['benefit_code']
        );
        $stmt->execute();
        $preauth_result = $stmt->get_result();
        $preauth = $preauth_result->fetch_assoc();

        // Save claim with copay information
        $sql = "INSERT INTO bills (
            claim_no,
            claim_form_no,
            invoice_no,
            service,
            provider,
            member_no,
            claim_nature,
            invoice_date,
            invoiced_amount,
            copay_amount,
            copay_type,
            copay_value,
            payable_amount,
            date_received,
            user_id,
            date_entered,
            corp_id,
            family_no,
            pri_dep,
            pre_auth_no
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURDATE(), ?, ?, ?, ?)";

        $stmt = $conn->prepare($sql);
        $copay_type = $copay ? $copay['copay_type'] : null;
        $copay_value = $copay ? $copay['copay_value'] : 0;
        $preauth_code = $preauth ? $preauth['code'] : 0;

        $stmt->bind_param(
            "ssssisssddsddssisii",
            $data['claim_no'],     // claim_no
            $data['claim_no'],     // claim_form_no
            $claim['invoiceNo'],   // invoice_no
            $claim['description'], // service
            $data['provider'],     // provider
            $data['member_no'],    // member_no
            $claim['benefit_code'],// claim_nature
            $data['invoice_date'], // invoice_date
            $claim['amount'],      // invoiced_amount
            $copay_amount,         // copay_amount
            $copay_type,          // copay_type
            $copay_value,         // copay_value
            $payable_amount,      // payable_amount
            $claim['dateReceived'],// date_received
            $_SESSION['user_id'],  // user_id
            $data['corp_id'],      // corp_id
            $data['family_no'],    // family_no
            $data['pri_dep'],      // pri_dep
            $preauth_code         // pre_auth_no
        );

        if (!$stmt->execute()) {
            throw new Exception("Failed to save claim: " . $stmt->error);
        }

        // Handle pre-auth update if exists
        if ($preauth) {
            $sql_update_preauth = "UPDATE pre_authorization 
                                 SET reserve = 0, 
                                     claim_no = ?,
                                     claim_date = CURDATE()
                                 WHERE code = ?";
            
            $stmt = $conn->prepare($sql_update_preauth);
            $stmt->bind_param("si", $data['claim_no'], $preauth['code']);
            
            if (!$stmt->execute()) {
                throw new Exception("Failed to update pre-auth: " . $stmt->error);
            }

            // Log the pre-auth attachment
            $sql_log = "INSERT INTO activity_log (
                user_id, 
                action, 
                table_name,
                record_id,
                new_values,
                action_date
            ) VALUES (?, 'UPDATE', 'pre_authorization', ?, ?, NOW())";

            $log_details = json_encode([
                'action' => 'Pre-auth attached to claim',
                'claim_no' => $data['claim_no'],
                'original_reserve' => $preauth['reserve'],
                'new_reserve' => 0
            ]);

            $stmt = $conn->prepare($sql_log);
            $stmt->bind_param("sis", 
                $_SESSION['user_id'], 
                $preauth['code'],
                $log_details
            );
            $stmt->execute();
        }
    }

    // Log the activity
    $action = $is_existing_claim ? 'UPDATE' : 'CREATE';
    $log_sql = "INSERT INTO activity_log (
        user_id,
        action,
        table_name,
        record_id,
        new_values,
        ip_address,
        user_agent,
        action_date
    ) VALUES (?, ?, 'bills', ?, ?, ?, ?, NOW())";

    $log_stmt = $conn->prepare($log_sql);
    $log_data = json_encode([
        'claim_no' => $data['claim_no'],
        'member_no' => $data['member_no'],
        'diagnoses' => $data['diagnoses'],
        'claim_count' => count($data['claims'])
    ]);
    $ip = $_SERVER['REMOTE_ADDR'];
    $user_agent = $_SERVER['HTTP_USER_AGENT'];

    $log_stmt->bind_param("ssssss",
        $_SESSION['user_id'],
        $action,
        $data['claim_no'],
        $log_data,
        $ip,
        $user_agent
    );
    $log_stmt->execute();

    $conn->commit();

    echo json_encode([
        'success' => true,
        'claim_no' => $data['claim_no'],
        'message' => $is_existing_claim ? 'Claim updated successfully' : 'Claim created successfully',
        'has_copay' => $copay_amount > 0,
        'copay_amount' => $copay_amount,
        'payable_amount' => $payable_amount
    ]);

} catch (Exception $e) {
    error_log("Error saving claim: " . $e->getMessage());
    if ($conn) {
        try {
            $conn->rollback();
        } catch (Exception $rollbackError) {
            // Ignore rollback errors as the transaction might not be active
        }
    }
    http_response_code(500);
    echo json_encode(['error' => $e->getMessage()]);
}

$conn->close();
?>