<?php
declare(strict_types=1);

session_start();

if (!isset($_SESSION['panel_user'])) {
    header('Location: index.php');
    exit;
}

if (($_SESSION['tipo_user'] ?? '') !== 'admin') {
    header('Location: dashboard.php');
    exit;
}

require_once dirname(__DIR__) . '/api/_auth_common.php';

const CHATBOT_FIXED_BASE_URL = 'https://zapbot.pro';

$db = new PDO('sqlite:' . dirname(__DIR__) . '/api/db.db');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

function cb_digits(string $value): string {
    return preg_replace('/\D+/', '', $value) ?: '';
}

function cb_token_preview(string $token): string {
    $token = trim($token);
    if ($token === '') {
        return '';
    }
    return substr($token, 0, 8) . '...' . substr($token, -6);
}

function cb_pseudo_mac(string $phone): string {
    $hex = strtoupper(substr(sha1($phone), 0, 12));
    return implode(':', str_split($hex, 2));
}

function cb_panel_expiry_to_chatbot($value): string {
    $raw = trim((string)$value);
    if ($raw === '') {
        return '';
    }
    if (ctype_digit($raw)) {
        $ts = (int)$raw;
        return $ts > 0 ? date('Y-m-d H:i:s', $ts) : '';
    }
    $ts = strtotime($raw);
    return $ts ? date('Y-m-d H:i:s', $ts) : '';
}

function cb_chatbot_expiry_to_panel($value): int {
    $raw = trim((string)$value);
    if ($raw === '') {
        return 0;
    }
    $ts = strtotime($raw);
    return $ts ? $ts : 0;
}

function cb_api_request(string $baseUrl, string $token, string $action, array $fields = []): array {
    $baseUrl = CHATBOT_FIXED_BASE_URL;
    $endpoint = rtrim($baseUrl, '/') . '/client-api';
    $post = array_merge(['action' => $action], $fields);
    $body = http_build_query($post);
    $headers = [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/x-www-form-urlencoded',
    ];

    $raw = false;
    $code = 0;

    if (function_exists('curl_init')) {
        $ch = curl_init($endpoint);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $body,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_CONNECTTIMEOUT => 8,
            CURLOPT_TIMEOUT => 30,
        ]);
        $raw = curl_exec($ch);
        $code = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        $curlError = curl_error($ch);
        curl_close($ch);

        if ($raw === false) {
            return ['ok' => false, 'http' => 0, 'error' => $curlError ?: 'Falha ao conectar no chatbot.'];
        }
    } else {
        $ctx = stream_context_create([
            'http' => [
                'method' => 'POST',
                'header' => implode("\r\n", $headers),
                'content' => $body,
                'timeout' => 30,
                'ignore_errors' => true,
            ],
        ]);

        $raw = @file_get_contents($endpoint, false, $ctx);
        $code = 200;

        if ($raw === false) {
            return ['ok' => false, 'http' => 0, 'error' => 'Falha ao conectar no chatbot.'];
        }
    }

    $json = json_decode((string)$raw, true);

    if (!is_array($json)) {
        return ['ok' => false, 'http' => $code, 'error' => 'Resposta inválida do chatbot.', 'raw' => (string)$raw];
    }

    if (!($json['ok'] ?? false)) {
        return ['ok' => false, 'http' => $code, 'error' => (string)($json['error'] ?? 'Erro retornado pelo chatbot.'), 'json' => $json];
    }

    return ['ok' => true, 'http' => $code, 'json' => $json];
}

function cb_panel_users(PDO $db): array {
    $rows = $db->query("SELECT mac, dns, username, password, status, vencimento, nome_cliente, whatsapp FROM usuarios WHERE (usuario_id IS NULL OR usuario_id=0)")->fetchAll(PDO::FETCH_ASSOC);
    return is_array($rows) ? $rows : [];
}

function cb_find_panel_by_phone(array $panelUsers, string $phone): ?array {
    foreach ($panelUsers as $row) {
        if (cb_digits((string)($row['whatsapp'] ?? '')) === $phone) {
            return $row;
        }
    }
    return null;
}

function cb_upsert_panel_user(PDO $db, array $panelUsers, array $client): string {
    $phone = cb_digits((string)($client['phone'] ?? ''));

    if ($phone === '') {
        return 'skipped';
    }

    $name = trim((string)($client['name'] ?? ''));
    $status = ((int)($client['is_blocked'] ?? 0) === 1) ? 'inativo' : 'ativo';
    $expires = cb_chatbot_expiry_to_panel($client['expires_at'] ?? '');
    $existing = cb_find_panel_by_phone($panelUsers, $phone);
    $mac = (string)($existing['mac'] ?? '');

    if ($mac !== '') {
        $db->prepare("UPDATE usuarios SET nome_cliente=?, whatsapp=?, status=?, vencimento=CASE WHEN ? > 0 THEN ? ELSE vencimento END WHERE mac=? AND (usuario_id IS NULL OR usuario_id=0)")
            ->execute([$name, $phone, $status, $expires, $expires, $mac]);
        return 'updated';
    }

    $mac = cb_pseudo_mac($phone);

    $db->prepare("INSERT OR IGNORE INTO usuarios (mac, username, password, dns, status, vencimento, nome_cliente, whatsapp, teste, usuario_id, login_mode, activation_code)
        VALUES (?, '', '', '', ?, ?, ?, ?, '0', 0, 'normal', '')")
        ->execute([$mac, $status, $expires > 0 ? (string)$expires : '', $name, $phone]);

    return 'created';
}

function cb_run_sync(PDO $db, array $cfg, bool $syncDeletes): array {
    $baseUrl = CHATBOT_FIXED_BASE_URL;
    $token = trim((string)($cfg['api_token'] ?? ''));

    if ($token === '') {
        return ['ok' => false, 'error' => 'Cole a chave key antes de sincronizar.'];
    }

    $list = cb_api_request($baseUrl, $token, 'clients_list');

    if (!($list['ok'] ?? false)) {
        return ['ok' => false, 'error' => $list['error'] ?? 'Falha ao listar clientes do ZapBot.'];
    }

    $clients = $list['json']['data'] ?? [];

    if (!is_array($clients)) {
        $clients = [];
    }

    $clientsByPhone = [];
    $clientsById = [];

    foreach ($clients as $client) {
        if (!is_array($client)) {
            continue;
        }

        $id = (int)($client['id'] ?? 0);
        $phone = cb_digits((string)($client['phone'] ?? ''));

        if ($id > 0) {
            $clientsById[$id] = $client;
        }

        if ($phone !== '') {
            $clientsByPhone[$phone] = $client;
        }
    }

    $panelUsers = cb_panel_users($db);
    $panelByMac = [];
    $pushed = 0;
    $createdRemote = 0;
    $updatedRemote = 0;
    $pulledCreated = 0;
    $pulledUpdated = 0;
    $deletedRemote = 0;
    $deletedPanel = 0;
    $errors = [];

    foreach ($panelUsers as $user) {
        $mac = (string)($user['mac'] ?? '');

        if ($mac !== '') {
            $panelByMac[$mac] = $user;
        }

        $phone = cb_digits((string)($user['whatsapp'] ?? ''));

        if ($phone === '') {
            continue;
        }

        $client = $clientsByPhone[$phone] ?? null;

        $fields = [
            'name' => trim((string)($user['nome_cliente'] ?? '')) ?: $phone,
            'phone' => $phone,
            'email' => '',
            'tags' => 'Painel',
            'notes' => 'Sincronizado pelo painel',
            'expires_at' => cb_panel_expiry_to_chatbot($user['vencimento'] ?? ''),
            'mac' => $mac,
            'm3u_url' => trim((string)($user['dns'] ?? '')),
        ];

        if (is_array($client) && (int)($client['id'] ?? 0) > 0) {
            $fields['id'] = (string)(int)$client['id'];
        }

        $save = cb_api_request($baseUrl, $token, 'clients_save', $fields);

        if (!($save['ok'] ?? false)) {
            $errors[] = $phone . ': ' . ($save['error'] ?? 'falha ao salvar');
            continue;
        }

        $remoteId = (int)($save['json']['id'] ?? ($client['id'] ?? 0));

        if ($remoteId > 0) {
            $updated = $db->prepare("UPDATE chatbot_sync_map SET chatbot_id=?, phone=?, updated_at=strftime('%s','now') WHERE panel_mac=?");
            $updated->execute([$remoteId, $phone, $mac]);

            if ($updated->rowCount() === 0) {
                $db->prepare("INSERT OR IGNORE INTO chatbot_sync_map (panel_mac, chatbot_id, phone, updated_at) VALUES (?, ?, ?, strftime('%s','now'))")
                    ->execute([$mac, $remoteId, $phone]);
            }
        }

        $pushed++;

        if (is_array($client)) {
            $updatedRemote++;
        } else {
            $createdRemote++;
        }
    }

    $panelUsersAfterPush = cb_panel_users($db);

    foreach ($clients as $client) {
        if (!is_array($client)) {
            continue;
        }

        $phone = cb_digits((string)($client['phone'] ?? ''));

        if ($phone === '' || cb_find_panel_by_phone($panelUsersAfterPush, $phone)) {
            continue;
        }

        $result = cb_upsert_panel_user($db, $panelUsersAfterPush, $client);

        if ($result === 'created') {
            $pulledCreated++;
        } elseif ($result === 'updated') {
            $pulledUpdated++;
        }
    }

    if ($syncDeletes) {
        $maps = $db->query("SELECT panel_mac, chatbot_id, phone FROM chatbot_sync_map")->fetchAll(PDO::FETCH_ASSOC) ?: [];

        foreach ($maps as $map) {
            $mac = (string)($map['panel_mac'] ?? '');
            $remoteId = (int)($map['chatbot_id'] ?? 0);
            $panelExists = isset($panelByMac[$mac]);
            $remoteExists = $remoteId > 0 && isset($clientsById[$remoteId]);

            if (!$panelExists && $remoteExists) {
                $delete = cb_api_request($baseUrl, $token, 'clients_delete', ['id' => (string)$remoteId]);

                if ($delete['ok'] ?? false) {
                    $deletedRemote++;
                    $db->prepare("DELETE FROM chatbot_sync_map WHERE panel_mac=?")->execute([$mac]);
                }
            } elseif ($panelExists && !$remoteExists && $remoteId > 0) {
                $db->prepare("DELETE FROM usuarios WHERE mac=? AND (usuario_id IS NULL OR usuario_id=0)")->execute([$mac]);
                $db->prepare("DELETE FROM chatbot_sync_map WHERE panel_mac=?")->execute([$mac]);
                $deletedPanel++;
            }
        }
    }

    $lastError = $errors ? implode(' | ', array_slice($errors, 0, 6)) : '';

    $db->prepare("UPDATE chatbot_integration_config SET last_sync_at=strftime('%s','now'), last_error=?, updated_at=strftime('%s','now') WHERE id=1")
        ->execute([$lastError]);

    return [
        'ok' => empty($errors),
        'pushed' => $pushed,
        'created_remote' => $createdRemote,
        'updated_remote' => $updatedRemote,
        'pulled_created' => $pulledCreated,
        'pulled_updated' => $pulledUpdated,
        'deleted_remote' => $deletedRemote,
        'deleted_panel' => $deletedPanel,
        'errors' => $errors,
    ];
}

if (empty($_SESSION['csrf_chatbot_sync'])) {
    $_SESSION['csrf_chatbot_sync'] = bin2hex(random_bytes(16));
}

$alert = '';
$alertType = 'success';
$syncResult = null;

try {
    $db->prepare("UPDATE chatbot_integration_config SET base_url=? WHERE id=1")->execute([CHATBOT_FIXED_BASE_URL]);
    $cfg = $db->query("SELECT * FROM chatbot_integration_config WHERE id=1")->fetch(PDO::FETCH_ASSOC) ?: [];
} catch (Throwable $e) {
    $cfg = [
        'base_url' => CHATBOT_FIXED_BASE_URL,
        'api_token' => '',
        'token_preview' => '',
        'last_sync_at' => 0,
        'last_error' => '',
    ];
    $alert = 'Tabela de integração não encontrada. Verifique se o banco já está importado corretamente.';
    $alertType = 'danger';
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $csrf = (string)($_POST['csrf'] ?? '');

    if (!hash_equals((string)$_SESSION['csrf_chatbot_sync'], $csrf)) {
        $alert = 'Sessão expirada. Recarregue a página e tente novamente.';
        $alertType = 'danger';
    } else {
        $action = (string)($_POST['action'] ?? '');

        if ($action === 'sync_key') {
            $tokenInput = trim((string)($_POST['api_token'] ?? ''));
            $token = $tokenInput !== '' ? $tokenInput : trim((string)($cfg['api_token'] ?? ''));

            if ($token === '') {
                $alert = 'Cole a chave key gerada no ZapBot antes de sincronizar.';
                $alertType = 'danger';
            } else {
                try {
                    $db->prepare("UPDATE chatbot_integration_config SET base_url=?, api_token=?, token_preview=?, last_error='', updated_at=strftime('%s','now') WHERE id=1")
                        ->execute([CHATBOT_FIXED_BASE_URL, $token, cb_token_preview($token)]);

                    $cfg = $db->query("SELECT * FROM chatbot_integration_config WHERE id=1")->fetch(PDO::FETCH_ASSOC) ?: [];

                    $syncResult = cb_run_sync($db, $cfg, false);

                    if ($syncResult['ok'] ?? false) {
                        $alert = 'Chave salva e sincronização concluída com sucesso.';
                        $alertType = 'success';
                    } else {
                        $alert = (string)($syncResult['error'] ?? 'Sincronização concluída com avisos.');
                        $alertType = 'warning';
                    }

                    $cfg = $db->query("SELECT * FROM chatbot_integration_config WHERE id=1")->fetch(PDO::FETCH_ASSOC) ?: [];
                } catch (Throwable $e) {
                    $alert = 'Erro ao salvar ou sincronizar: ' . $e->getMessage();
                    $alertType = 'danger';
                }
            }
        }
    }
}

include './includes/header.php';
?>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">

<style>
.dns-wrap{
    width:100%;
    max-width:none;
    margin:0;
    padding:0 18px;
}
.dns-card{
    border-radius:18px;
    overflow:hidden;
    width:100%;
    margin-bottom:18px;
}
.dns-header{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:14px;
    padding:18px 22px;
}
.dns-title{
    display:flex;
    align-items:center;
    gap:14px;
}
.dns-title .ic{
    width:44px;
    height:44px;
    min-width:44px;
    border-radius:14px;
    background:rgba(25,135,84,.10);
    border:1px solid rgba(25,135,84,.20);
    display:flex;
    align-items:center;
    justify-content:center;
}
.dns-title .ic i{
    font-size:24px;
    color:#198754;
}
.dns-title h5{
    margin:0;
    font-weight:900;
}
.dns-title span{
    display:block;
    margin-top:3px;
    font-size:13px;
    color:rgba(255,255,255,.55);
}
.badge-soft{
    display:inline-flex;
    align-items:center;
    gap:7px;
    padding:8px 12px;
    border-radius:999px;
    background:rgba(25,135,84,.10);
    border:1px solid rgba(25,135,84,.20);
    color:#198754;
    font-weight:900;
    white-space:nowrap;
}
.input-radius{
    border-radius:14px !important;
    min-height:48px;
}
.save-btn{
    border-radius:14px;
    min-height:46px;
    font-weight:900;
    padding-left:22px;
    padding-right:22px;
}
.info-box{
    background:rgba(0,0,0,.03);
    border:1px solid rgba(0,0,0,.08);
    border-radius:14px;
    padding:12px 14px;
    font-weight:700;
}
.tutorial-list{
    display:grid;
    grid-template-columns:repeat(4,minmax(0,1fr));
    gap:12px;
}
.tutorial-step{
    background:rgba(0,0,0,.03);
    border:1px solid rgba(0,0,0,.08);
    border-radius:16px;
    padding:14px;
}
.tutorial-step .num{
    width:32px;
    height:32px;
    border-radius:999px;
    background:rgba(25,135,84,.12);
    border:1px solid rgba(25,135,84,.22);
    color:#198754;
    display:flex;
    align-items:center;
    justify-content:center;
    font-weight:1000;
    margin-bottom:10px;
}
.tutorial-step strong{
    display:block;
    font-weight:1000;
    margin-bottom:4px;
}
.tutorial-step span{
    display:block;
    font-size:13px;
    color:rgba(255,255,255,.58);
}
.alert{
    border-radius:14px;
}
@media(max-width:991px){
    .tutorial-list{
        grid-template-columns:repeat(2,minmax(0,1fr));
    }
}
@media(max-width:575px){
    .dns-wrap{
        padding:0 8px;
    }
    .dns-header{
        align-items:flex-start;
        padding:16px;
    }
    .dns-title .ic{
        width:40px;
        height:40px;
        min-width:40px;
    }
    .dns-title .ic i{
        font-size:22px;
    }
    .dns-title h5{
        font-size:18px;
    }
    .badge-soft{
        padding:7px 10px;
        font-size:12px;
    }
    .tutorial-list{
        grid-template-columns:1fr;
    }
    .save-btn{
        width:100%;
    }
}
.dns-title span,
.tutorial-step span,
.text-muted,
.info-box,
.info-box strong,
.info-box a,
.alert,
.form-label,
small,
.dns-card,
.dns-card .card-body,
.tutorial-step,
.tutorial-step strong {
    color: #111 !important;
}

.dns-title h5,
.tutorial-step .num,
label,
strong {
    color: #000 !important;
}

.badge-soft {
    color: #198754 !important;
}

input::placeholder {
    color: #555 !important;
    opacity: 1 !important;
}
</style>

<div class="dns-wrap">
    <div class="card radius-10 dns-card">
        <div class="card-header bg-transparent dns-header">
            <div class="dns-title">
                <div class="ic"><i class="bi bi-whatsapp"></i></div>
                <div>
                    <h5>Chatbot WhatsApp</h5>
                    <span>Cole a chave key do ZapBot e sincronize os clientes do painel</span>
                </div>
            </div>

            <div class="dns-actions">
                <span class="badge-soft"><i class="bi bi-link-45deg"></i> Integração</span>
            </div>
        </div>

        <div class="card-body">
            <?php if ($alert): ?>
                <div class="alert alert-<?= htmlspecialchars($alertType, ENT_QUOTES, 'UTF-8') ?>">
                    <?= htmlspecialchars($alert, ENT_QUOTES, 'UTF-8') ?>
                </div>
            <?php endif; ?>

            <form method="post" class="row g-3">
                <input type="hidden" name="csrf" value="<?= htmlspecialchars((string)$_SESSION['csrf_chatbot_sync'], ENT_QUOTES, 'UTF-8') ?>">
                <input type="hidden" name="action" value="sync_key">

                <div class="col-lg-9 col-md-8 col-12">
                    <label class="form-label" for="api_token" style="font-weight:900;">Chave key da API</label>
                    <input
                        class="form-control input-radius"
                        id="api_token"
                        name="api_token"
                        type="password"
                        placeholder="<?= !empty($cfg['token_preview']) ? 'Deixe em branco para usar a key salva: ' . htmlspecialchars((string)$cfg['token_preview'], ENT_QUOTES, 'UTF-8') : 'Cole aqui a chave key gerada no ZapBot' ?>"
                        value=""
                    >
                    <?php if (!empty($cfg['token_preview'])): ?>
                        <small class="text-muted">Key salva: <?= htmlspecialchars((string)$cfg['token_preview'], ENT_QUOTES, 'UTF-8') ?></small>
                    <?php endif; ?>
                </div>

                <div class="col-lg-3 col-md-4 col-12 d-flex align-items-end">
                    <button class="btn btn-success save-btn w-100" type="submit">
                        <i class="bi bi-arrow-repeat"></i> Sincronizar
                    </button>
                </div>

                <div class="col-12">
                    <div class="info-box">
                        <strong>URL do ZapBot:</strong>
                        <a href="<?= htmlspecialchars(CHATBOT_FIXED_BASE_URL, ENT_QUOTES, 'UTF-8') ?>" target="_blank">
                            <?= htmlspecialchars(CHATBOT_FIXED_BASE_URL, ENT_QUOTES, 'UTF-8') ?>
                        </a>
                    </div>
                </div>
            </form>

            <?php if (is_array($syncResult)): ?>
                <div class="alert alert-info mt-3 mb-0">
                    Enviados: <strong><?= (int)($syncResult['pushed'] ?? 0) ?></strong> |
                    Criados no ZapBot: <strong><?= (int)($syncResult['created_remote'] ?? 0) ?></strong> |
                    Atualizados no ZapBot: <strong><?= (int)($syncResult['updated_remote'] ?? 0) ?></strong> |
                    Criados no painel: <strong><?= (int)($syncResult['pulled_created'] ?? 0) ?></strong> |
                    Atualizados no painel: <strong><?= (int)($syncResult['pulled_updated'] ?? 0) ?></strong>
                </div>

                <?php if (!empty($syncResult['errors'])): ?>
                    <div class="alert alert-warning mt-3 mb-0">
                        <?= htmlspecialchars(implode(' | ', array_slice($syncResult['errors'], 0, 6)), ENT_QUOTES, 'UTF-8') ?>
                    </div>
                <?php endif; ?>
            <?php elseif (!empty($cfg['last_sync_at'])): ?>
                <div class="alert alert-secondary mt-3 mb-0">
                    Última sincronização: <?= date('d/m/Y H:i', (int)$cfg['last_sync_at']) ?>
                </div>
            <?php endif; ?>
        </div>
    </div>

    <div class="card radius-10 dns-card">
        <div class="card-header bg-transparent dns-header">
            <div class="dns-title">
                <div class="ic"><i class="bi bi-info-circle-fill"></i></div>
                <div>
                    <h5>Tutorial de integração</h5>
                    <span>Como gerar a chave key e sincronizar com o painel</span>
                </div>
            </div>

            <div class="dns-actions">
                <span class="badge-soft"><i class="bi bi-book"></i> Passo a passo</span>
            </div>
        </div>

        <div class="card-body">
            <div class="tutorial-list">
                <div class="tutorial-step">
                    <div class="num">1</div>
                    <strong>Acesse o ZapBot</strong>
                    <span>Entre no site zapbot.pro pelo navegador.</span>
                </div>

                <div class="tutorial-step">
                    <div class="num">2</div>
                    <strong>Crie sua conta</strong>
                    <span>Faça o cadastro ou entre na sua conta já existente.</span>
                </div>

                <div class="tutorial-step">
                    <div class="num">3</div>
                    <strong>Gere a key</strong>
                    <span>No menu API, gere a chave key de integração.</span>
                </div>

                <div class="tutorial-step">
                    <div class="num">4</div>
                    <strong>Sincronize</strong>
                    <span>Cole a key neste painel e clique em Sincronizar.</span>
                </div>
            </div>
        </div>
    </div>
</div>

<?php include './includes/footer.php'; ?>