<?php 
if (!isset($GLOBALS['con']) || !($GLOBALS['con'] instanceof mysqli)) {
    if (file_exists('../../../' . ($_REQUEST['tenant'] ?? '') . '/config.php')) {
        require_once('../../../' . ($_REQUEST['tenant'] ?? '') . '/config.php');
    }
    if (file_exists('/config.php')) {
        require_once('/config.php');
    }
}

if (!isset($GLOBALS['con']) || !($GLOBALS['con'] instanceof mysqli)) {
    http_response_code(500);
    exit('DB connection unavailable');
}

function jumpPhraseCsvTableExists(string $table): bool
{
    $table = $GLOBALS['con']->real_escape_string($table);
    $res = $GLOBALS['con']->query("SHOW TABLES LIKE '$table'");

    return $res && $res->num_rows > 0;
}

function jumpPhraseCsvColumnExists(string $table, string $column): bool
{
    $table = $GLOBALS['con']->real_escape_string($table);
    $column = $GLOBALS['con']->real_escape_string($column);
    $res = $GLOBALS['con']->query("SHOW COLUMNS FROM `$table` LIKE '$column'");

    return $res && $res->num_rows > 0;
}

function jumpPhraseCsvGroupsEnabled(): bool
{
    return jumpPhraseCsvTableExists('dd_phrase_groups') && jumpPhraseCsvColumnExists('dd_phrases', 'group_id');
}

function jumpPhraseCsvDownloadHeaders(string $filename): void
{
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    header('Pragma: no-cache');
    header('Expires: 0');
}

function jumpPhraseCsvJson(array $data, int $status = 200): void
{
    while (ob_get_level() > 0) {
        ob_end_clean();
    }

    http_response_code($status);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($data);
    exit;
}

function jumpPhraseCsvHeaderKey(string $value): string
{
    $value = preg_replace('/^\xEF\xBB\xBF/', '', $value);
    return strtolower(trim($value));
}

function jumpPhraseCsvResolveGroupId(string $groupName, array &$warnings): ?int
{
    $groupName = trim($groupName);
    if ($groupName === '' || !jumpPhraseCsvGroupsEnabled()) {
        return null;
    }

    $stmt = $GLOBALS['con']->prepare("SELECT `id` FROM `dd_phrase_groups` WHERE `group_name` = ? AND `status` = 1 LIMIT 1");
    $stmt->bind_param('s', $groupName);
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res ? $res->fetch_assoc() : null;
    $stmt->close();

    if (!empty($row['id'])) {
        return (int)$row['id'];
    }

    if (count($warnings) < 12) {
        $warnings[] = 'Group not found: ' . $groupName;
    }

    return null;
}

function jumpPhraseCsvCodeExists(string $code): bool
{
    $stmt = $GLOBALS['con']->prepare("SELECT `id` FROM `dd_phrases` WHERE `phrasecode` = ? LIMIT 1");
    $stmt->bind_param('s', $code);
    $stmt->execute();
    $res = $stmt->get_result();
    $exists = $res && $res->num_rows > 0;
    $stmt->close();

    return $exists;
}

function jumpPhraseCsvInsert(string $code, string $phrase, ?int $groupId): bool
{
    try {
        if (jumpPhraseCsvGroupsEnabled()) {
            if ($groupId === null) {
                $stmt = $GLOBALS['con']->prepare("INSERT INTO `dd_phrases` (`phrasecode`, `phrase`, `group_id`) VALUES (?, ?, NULL)");
                if (!$stmt) return false;
                $stmt->bind_param('ss', $code, $phrase);
            } else {
                $stmt = $GLOBALS['con']->prepare("INSERT INTO `dd_phrases` (`phrasecode`, `phrase`, `group_id`) VALUES (?, ?, ?)");
                if (!$stmt) return false;
                $stmt->bind_param('ssi', $code, $phrase, $groupId);
            }
        } else {
            $stmt = $GLOBALS['con']->prepare("INSERT INTO `dd_phrases` (`phrasecode`, `phrase`) VALUES (?, ?)");
            if (!$stmt) return false;
            $stmt->bind_param('ss', $code, $phrase);
        }

        $ok = $stmt->execute();
        $stmt->close();

        return $ok;
    } catch (Throwable $e) {
        return false;
    }
}

$action = strtolower(trim((string)($_REQUEST['action'] ?? 'export')));

if ($action === 'template') {
    jumpPhraseCsvDownloadHeaders('standard_phrases_template.csv');
    $out = fopen('php://output', 'w');
    fputcsv($out, ['phrasecode', 'phrase', 'group_name']);
    fputcsv($out, ['EXAMPLE', 'Enter the standard phrase text here', 'adefect']);
    fclose($out);
    exit;
}

if ($action === 'export') {
    jumpPhraseCsvDownloadHeaders('standard_phrases_' . date('Ymd_His') . '.csv');
    $out = fopen('php://output', 'w');
    fputcsv($out, ['phrasecode', 'phrase', 'group_name']);

    if (jumpPhraseCsvGroupsEnabled()) {
        $sql = "
            SELECT p.`phrasecode`, p.`phrase`, COALESCE(g.`group_name`, '') AS `group_name`
            FROM `dd_phrases` p
            LEFT JOIN `dd_phrase_groups` g ON g.`id` = p.`group_id`
            ORDER BY p.`phrasecode` ASC, p.`id` ASC
        ";
    } else {
        $sql = "
            SELECT p.`phrasecode`, p.`phrase`, '' AS `group_name`
            FROM `dd_phrases` p
            ORDER BY p.`phrasecode` ASC, p.`id` ASC
        ";
    }

    $res = $GLOBALS['con']->query($sql);
    if ($res) {
        while ($row = $res->fetch_assoc()) {
            fputcsv($out, [
                (string)($row['phrasecode'] ?? ''),
                (string)($row['phrase'] ?? ''),
                (string)($row['group_name'] ?? '')
            ]);
        }
    }

    fclose($out);
    exit;
}

if ($action !== 'import') {
    jumpPhraseCsvJson(['success' => false, 'message' => 'Unknown CSV action.'], 400);
}

if (empty($_FILES['csv']['tmp_name']) || !is_uploaded_file($_FILES['csv']['tmp_name'])) {
    jumpPhraseCsvJson(['success' => false, 'message' => 'Choose a CSV file to import.'], 400);
}

$handle = fopen($_FILES['csv']['tmp_name'], 'r');
if (!$handle) {
    jumpPhraseCsvJson(['success' => false, 'message' => 'Unable to read CSV file.'], 400);
}

$headers = fgetcsv($handle);
if (!$headers || !is_array($headers)) {
    fclose($handle);
    jumpPhraseCsvJson(['success' => false, 'message' => 'CSV header row is missing.'], 400);
}

$columns = [];
foreach ($headers as $index => $header) {
    $key = jumpPhraseCsvHeaderKey((string)$header);
    if ($key === 'code') {
        $key = 'phrasecode';
    } elseif ($key === 'group') {
        $key = 'group_name';
    }
    $columns[$key] = $index;
}

if (!isset($columns['phrasecode']) || !isset($columns['phrase'])) {
    fclose($handle);
    jumpPhraseCsvJson([
        'success' => false,
        'message' => 'CSV must include phrasecode and phrase columns. The id column is intentionally ignored.'
    ], 400);
}

$inserted = 0;
$skipped = 0;
$failed = 0;
$warnings = [];
$seenCodes = [];
$line = 1;

while (($row = fgetcsv($handle)) !== false) {
    $line++;
    $code = trim((string)($row[$columns['phrasecode']] ?? ''));
    $phrase = trim((string)($row[$columns['phrase']] ?? ''));
    $groupName = isset($columns['group_name']) ? trim((string)($row[$columns['group_name']] ?? '')) : '';

    if ($code === '' && $phrase === '') {
        continue;
    }

    if ($code === '' || $phrase === '') {
        $skipped++;
        if (count($warnings) < 12) {
            $warnings[] = 'Line ' . $line . ' skipped: phrasecode and phrase are required.';
        }
        continue;
    }

    if (strlen($code) > 10) {
        $skipped++;
        if (count($warnings) < 12) {
            $warnings[] = 'Line ' . $line . ' skipped: phrasecode is longer than 10 characters (' . $code . ').';
        }
        continue;
    }

    $codeKey = strtolower($code);
    if (isset($seenCodes[$codeKey])) {
        $skipped++;
        if (count($warnings) < 12) {
            $warnings[] = 'Line ' . $line . ' skipped: duplicate code in CSV (' . $code . ').';
        }
        continue;
    }
    $seenCodes[$codeKey] = true;

    if (jumpPhraseCsvCodeExists($code)) {
        $skipped++;
        if (count($warnings) < 12) {
            $warnings[] = 'Line ' . $line . ' skipped: code already exists (' . $code . ').';
        }
        continue;
    }

    $groupId = jumpPhraseCsvResolveGroupId($groupName, $warnings);
    if (jumpPhraseCsvInsert($code, $phrase, $groupId)) {
        $inserted++;
    } else {
        $failed++;
        if (count($warnings) < 12) {
            $warnings[] = 'Line ' . $line . ' failed to import.';
        }
    }
}

$message = 'Import complete: ' . $inserted . ' added, ' . $skipped . ' skipped' . ($failed ? ', ' . $failed . ' failed' : '') . '.';
if (!empty($warnings[0])) {
    $message .= ' First issue: ' . $warnings[0];
}

fclose($handle);

jumpPhraseCsvJson([
    'success' => $failed === 0,
    'message' => $message,
    'inserted' => $inserted,
    'skipped' => $skipped,
    'failed' => $failed,
    'warnings' => $warnings
]);
