<?php
declare(strict_types=1);

header('Content-Type: application/json; charset=utf-8');
ini_set('display_errors', '0');
error_reporting(E_ALL);

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_start();
}

function respond(int $statusCode, array $payload): void
{
    http_response_code($statusCode);
    echo json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    exit;
}

function first_existing_session_key(array $keys, $default = null)
{
    foreach ($keys as $key) {
        if (array_key_exists($key, $_SESSION) && $_SESSION[$key] !== '' && $_SESSION[$key] !== null) {
            return $_SESSION[$key];
        }
    }
    return $default;
}

function normalize_row_keys(array $row): array
{
    $out = [];
    foreach ($row as $key => $value) {
        if (is_int($key)) {
            continue;
        }
        $out[strtolower((string) $key)] = $value;
    }
    return $out;
}

function find_table(PDO $pdo, array $candidates): ?string
{
    foreach ($candidates as $table) {
        try {
            $stmt = $pdo->query("SHOW TABLES LIKE " . $pdo->quote($table));
            if ($stmt && $stmt->fetchColumn()) {
                return $table;
            }
        } catch (Throwable $e) {
            // ignore and keep trying
        }
    }
    return null;
}

function find_columns(PDO $pdo, string $table): array
{
    $columns = [];
    $stmt = $pdo->query("SHOW COLUMNS FROM `{$table}`");
    if ($stmt) {
        foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
            $field = strtolower((string) ($row['Field'] ?? ''));
            if ($field !== '') {
                $columns[$field] = true;
            }
        }
    }
    return $columns;
}

function first_column(array $available, array $candidates): ?string
{
    foreach ($candidates as $column) {
        if (isset($available[strtolower($column)])) {
            return $column;
        }
    }
    return null;
}

function fetch_one(PDO $pdo, string $table, array $where, array $selectCandidates): ?array
{
    $columns = find_columns($pdo, $table);
    if (!$columns) {
        return null;
    }

    $select = [];
    foreach ($selectCandidates as $alias => $candidates) {
        $col = first_column($columns, $candidates);
        if ($col) {
            $select[] = "`{$col}` AS `{$alias}`";
        }
    }
    if (!$select) {
        $select[] = '*';
    }

    $whereSql = [];
    $params = [];
    foreach ($where as $name => $value) {
        $col = first_column($columns, [$name]);
        if ($col) {
            $whereSql[] = "`{$col}` = :{$name}";
            $params[$name] = $value;
        }
    }
    if (!$whereSql) {
        return null;
    }

    $sql = "SELECT " . implode(', ', $select) . " FROM `{$table}` WHERE " . implode(' AND ', $whereSql) . " LIMIT 1";
    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    return $row ?: null;
}

function fetch_all(PDO $pdo, string $table, array $where, array $selectCandidates, ?string $orderBy = null): array
{
    $columns = find_columns($pdo, $table);
    if (!$columns) {
        return [];
    }

    $select = [];
    foreach ($selectCandidates as $alias => $candidates) {
        $col = first_column($columns, $candidates);
        if ($col) {
            $select[] = "`{$col}` AS `{$alias}`";
        }
    }
    if (!$select) {
        $select[] = '*';
    }

    $whereSql = [];
    $params = [];
    foreach ($where as $name => $value) {
        $col = first_column($columns, [$name]);
        if ($col) {
            $whereSql[] = "`{$col}` = :{$name}";
            $params[$name] = $value;
        }
    }

    $sql = "SELECT " . implode(', ', $select) . " FROM `{$table}`";
    if ($whereSql) {
        $sql .= " WHERE " . implode(' AND ', $whereSql);
    }
    if ($orderBy && isset($columns[strtolower($orderBy)])) {
        $sql .= " ORDER BY `{$orderBy}` ASC";
    }

    $stmt = $pdo->prepare($sql);
    $stmt->execute($params);
    return $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
}

function detect_pdo_connection(): ?PDO
{
    $possibleFiles = [
        __DIR__ . '/db.php',
        __DIR__ . '/database.php',
        __DIR__ . '/config.php',
        __DIR__ . '/../db.php',
        __DIR__ . '/../database.php',
        __DIR__ . '/../config.php',
    ];

    foreach ($possibleFiles as $file) {
        if (is_file($file)) {
            require_once $file;
        }
    }

    foreach (['pdo', 'db', 'conn', 'database', 'mysqli'] as $varName) {
        if (isset($GLOBALS[$varName]) && $GLOBALS[$varName] instanceof PDO) {
            return $GLOBALS[$varName];
        }
    }

    return null;
}

try {
    $sessionId = first_existing_session_key(['app_session_id', 'session_id', 'active_session_id']);
    $familyId = first_existing_session_key(['family_id', 'active_family_id', 'logged_in_family_id']);
    $caregiverId = first_existing_session_key(['caregiver_id', 'active_caregiver_id', 'logged_in_caregiver_id']);
    $familySlug = first_existing_session_key(['family_slug', 'active_family_slug']);
    $caregiverUsername = first_existing_session_key(['caregiver_username', 'username', 'active_caregiver_username']);
    $caregiverName = first_existing_session_key(['caregiver_name', 'active_caregiver_name', 'display_name'], 'Caregiver');

    if (!$sessionId && !$caregiverId && !$familyId && !$familySlug && !$caregiverUsername) {
        respond(401, [
            'success' => false,
            'message' => 'No active caregiver session.'
        ]);
    }

    $family = null;
    $caregiver = null;
    $clients = [];
    $caregivers = [];

    $pdo = detect_pdo_connection();

    if ($pdo instanceof PDO) {
        $familyTable = find_table($pdo, ['families', 'family_accounts', 'family']);
        $caregiverTable = find_table($pdo, ['caregivers', 'family_caregivers', 'caregiver_accounts']);
        $clientTable = find_table($pdo, ['clients', 'patients', 'family_clients']);

        if ($familyTable) {
            $familyWhere = [];
            if ($familyId) {
                $familyWhere['id'] = (int) $familyId;
            } elseif ($familySlug) {
                $familyWhere['family_slug'] = (string) $familySlug;
            }

            if ($familyWhere) {
                $family = fetch_one($pdo, $familyTable, $familyWhere, [
                    'id' => ['id', 'family_id'],
                    'family_name' => ['family_name', 'name'],
                    'family_slug' => ['family_slug', 'slug'],
                ]);
            }
        }

        if ($caregiverTable) {
            $caregiverWhere = [];
            if ($caregiverId) {
                $caregiverWhere['id'] = (int) $caregiverId;
            } elseif ($caregiverUsername) {
                $caregiverWhere['username'] = (string) $caregiverUsername;
            }
            if ($familyId) {
                $caregiverWhere['family_id'] = (int) $familyId;
            }

            if ($caregiverWhere) {
                $caregiver = fetch_one($pdo, $caregiverTable, $caregiverWhere, [
                    'id' => ['id', 'caregiver_id'],
                    'name' => ['name', 'full_name', 'caregiver_name'],
                    'username' => ['username', 'login_username'],
                    'family_id' => ['family_id'],
                ]);
            }

            if ($familyId) {
                $caregivers = fetch_all($pdo, $caregiverTable, ['family_id' => (int) $familyId], [
                    'id' => ['id', 'caregiver_id'],
                    'name' => ['name', 'full_name', 'caregiver_name'],
                    'username' => ['username', 'login_username'],
                ], 'name');
            }
        }

        if ($clientTable && $familyId) {
            $clients = fetch_all($pdo, $clientTable, ['family_id' => (int) $familyId], [
                'id' => ['id', 'client_id', 'patient_id'],
                'name' => ['name', 'full_name', 'client_name', 'patient_name'],
            ], 'name');
        }
    }

    if (!$family) {
        $family = [
            'id' => $familyId ? (int) $familyId : null,
            'family_name' => $familySlug ? ucwords(str_replace(['-', '_'], ' ', (string) $familySlug)) : 'Family',
            'family_slug' => $familySlug ? (string) $familySlug : ''
        ];
    }

    if (!$caregiver) {
        $caregiver = [
            'id' => $caregiverId ? (int) $caregiverId : null,
            'name' => (string) $caregiverName,
            'username' => $caregiverUsername ? (string) $caregiverUsername : ''
        ];
    }

    if (!$family['id'] && isset($caregiver['family_id'])) {
        $family['id'] = (int) $caregiver['family_id'];
    }

    respond(200, [
        'success' => true,
        'session' => [
            'session_id' => $sessionId,
            'family_id' => $family['id'] ?? null,
            'caregiver_id' => $caregiver['id'] ?? null,
        ],
        'family' => [
            'id' => $family['id'] ?? null,
            'family_name' => $family['family_name'] ?? 'Family',
            'family_slug' => $family['family_slug'] ?? '',
        ],
        'caregiver' => [
            'id' => $caregiver['id'] ?? null,
            'name' => $caregiver['name'] ?? 'Caregiver',
            'username' => $caregiver['username'] ?? '',
        ],
        'caregivers' => array_values(array_map(static function (array $row): array {
            $row = normalize_row_keys($row);
            return [
                'id' => $row['id'] ?? null,
                'name' => $row['name'] ?? '',
                'username' => $row['username'] ?? '',
            ];
        }, $caregivers)),
        'clients' => array_values(array_map(static function (array $row): array {
            $row = normalize_row_keys($row);
            return [
                'id' => $row['id'] ?? null,
                'name' => $row['name'] ?? '',
            ];
        }, $clients)),
    ]);
} catch (Throwable $e) {
    error_log('family_context.php error: ' . $e->getMessage());
    respond(500, [
        'success' => false,
        'message' => 'Server error loading family context.'
    ]);
}
