<?php
declare(strict_types=1);

require_once __DIR__ . '/cma-config.php';

function cma_pdo(): PDO
{
    static $pdo = null;

    if ($pdo instanceof PDO) {
        return $pdo;
    }

    $dsn = 'mysql:host=' . CMA_DB_HOST . ';dbname=' . CMA_DB_NAME . ';charset=' . CMA_DB_CHARSET;

    $pdo = new PDO($dsn, CMA_DB_USER, CMA_DB_PASS, [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    ]);

    return $pdo;
}

function cma_h(?string $value): string
{
    return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}

function cma_money($value): string
{
    if ($value === null || $value === '' || !is_numeric($value)) {
        return '';
    }

    return '$' . number_format((float)$value, 0);
}

function cma_number($value): string
{
    if ($value === null || $value === '' || !is_numeric($value)) {
        return '';
    }

    return number_format((float)$value, 0);
}

function cma_percent($value): string
{
    if ($value === null || $value === '' || !is_numeric($value)) {
        return '';
    }

    return number_format((float)$value, 1) . '%';
}

function cma_date($value): string
{
    if (empty($value)) {
        return '';
    }

    $ts = strtotime((string)$value);

    if ($ts === false) {
        return (string)$value;
    }

    return date('m/d/Y', $ts);
}

function cma_normalize_listing_id(string $value): ?string
{
    $value = strtoupper(trim($value));
    $value = preg_replace('/[^A-Z0-9]/', '', $value);

    if ($value === '') {
        return null;
    }

    $value = preg_replace('/^NST/', '', $value);

    if (!preg_match('/^\d{7}$/', $value)) {
        return null;
    }

    return 'NST' . $value;
}

function cma_load_listing_ids(): array
{
    if (!file_exists(CMA_LISTINGS_FILE)) {
        return [];
    }

    $json = file_get_contents(CMA_LISTINGS_FILE);
    $data = json_decode((string)$json, true);

    if (!is_array($data)) {
        return [];
    }

    $out = [];

    foreach ($data as $id) {
        $normalized = cma_normalize_listing_id((string)$id);
        if ($normalized !== null) {
            $out[] = $normalized;
        }
    }

    return array_values(array_unique($out));
}

function cma_save_listing_ids(array $ids): void
{
    $clean = [];

    foreach ($ids as $id) {
        $normalized = cma_normalize_listing_id((string)$id);
        if ($normalized !== null) {
            $clean[] = $normalized;
        }
    }

    $clean = array_values(array_unique($clean));

    file_put_contents(
        CMA_LISTINGS_FILE,
        json_encode($clean, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
    );
}

function cma_load_subject(): array
{
    if (!file_exists(CMA_SUBJECT_FILE)) {
        return [];
    }

    $json = file_get_contents(CMA_SUBJECT_FILE);
    $data = json_decode((string)$json, true);

    return is_array($data) ? $data : [];
}

function cma_save_subject(array $subject): void
{
    file_put_contents(
        CMA_SUBJECT_FILE,
        json_encode($subject, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
    );
}

function cma_address(array $row): string
{
    $parts = [
        $row['StreetNumber'] ?? '',
        $row['StreetDirPrefix'] ?? '',
        $row['StreetName'] ?? '',
        $row['StreetSuffix'] ?? '',
        $row['StreetDirSuffix'] ?? '',
    ];

    $address = trim(preg_replace('/\s+/', ' ', implode(' ', $parts)));

    if (!empty($row['UnitNumber'])) {
        $address .= ' #' . $row['UnitNumber'];
    }

    return $address;
}

function cma_fetch_properties(array $listingIds): array
{
    if (empty($listingIds)) {
        return [];
    }

    $pdo = cma_pdo();

    $placeholders = implode(',', array_fill(0, count($listingIds), '?'));

    $sql = "
        SELECT *
        FROM `" . CMA_TABLE_LISTINGS . "`
        WHERE ListingId IN ($placeholders)
    ";

    $stmt = $pdo->prepare($sql);
    $stmt->execute($listingIds);

    $rows = $stmt->fetchAll();

    $byId = [];

    foreach ($rows as $row) {
        $byId[$row['ListingId']] = $row;
    }

    $ordered = [];

    foreach ($listingIds as $id) {
        if (isset($byId[$id])) {
            $ordered[] = $byId[$id];
        }
    }

    return $ordered;
}

function cma_fetch_thumbnail_map(array $listingIds): array
{
    if (empty($listingIds)) {
        return [];
    }

    $pdo = cma_pdo();

    $placeholders = implode(',', array_fill(0, count($listingIds), '?'));

    $sql = "
        SELECT ResourceRecordID, MediaKey
        FROM `" . CMA_TABLE_MEDIA . "`
        WHERE ResourceRecordID IN ($placeholders)
        ORDER BY ResourceRecordID ASC, MediaObjectID ASC
    ";

    $stmt = $pdo->prepare($sql);
    $stmt->execute($listingIds);

    $map = [];

    foreach ($stmt->fetchAll() as $row) {
        $id = $row['ResourceRecordID'] ?? '';
        if ($id !== '' && !isset($map[$id])) {
            $map[$id] = $row['MediaKey'] ?? '';
        }
    }

    return $map;
}

function cma_photo_url(array $row, array $thumbnailMap): string
{
    $id = $row['ListingId'] ?? '';

    if ($id !== '' && !empty($thumbnailMap[$id])) {
        return CMA_WAS_SERVER_URL . $thumbnailMap[$id] . '.MedRes.jpeg';
    }

    return CMA_PHOTO_FALLBACK;
}

function cma_sp_lp(array $row): string
{
    $sale = $row['ClosePrice'] ?? null;
    $list = $row['ListPrice'] ?? null;

    if (!is_numeric($sale) || !is_numeric($list) || (float)$list <= 0) {
        return '';
    }

    return cma_percent(((float)$sale / (float)$list) * 100);
}

function cma_price_per_sqft($price, $sqft): string
{
    if (!is_numeric($price) || !is_numeric($sqft) || (float)$sqft <= 0) {
        return '';
    }

    return '$' . number_format(((float)$price / (float)$sqft), 0);
}