#!/bin/bash
# Instalador revisado - Painel Video
# Baseado no instalador original fornecido pelo usuário.
# Mantém: painelvideo, banco video, /home/painelvideo/public_html,
# build dos dois APKs e modo --ssl.

set -Eeuo pipefail

dominio_source_instalador="https://installvox.udiwebsistem.com.br/2026/video"

# Cores
EfeitoCorTitulo="\033[0;35m"
EfeitoCorOK="\033[0;32m"
EfeitoCorAlerta="\033[1;33m"
EfeitoCorErro="\033[0;31m"
EfeitoFecha="\033[0m"

PAINEL_USER="painelvideo"
PAINEL_HOME="/home/painelvideo"
WEB_ROOT="$PAINEL_HOME/public_html"
DB_NAME="video"
DB_USER="painelvideo"
LOG_FILE="/var/log/instalador-painel-video.log"

senha_ftp="$(openssl rand -base64 18 | tr -dc 'A-Za-z0-9' | head -c 15)"
senha_painel_mysql="$(openssl rand -base64 18 | tr -dc 'A-Za-z0-9' | head -c 15)"
senha_admin_painel="$(openssl rand -base64 14 | tr -dc 'A-Za-z0-9' | head -c 10)"

exec > >(tee -a "$LOG_FILE") 2>&1

erro() {
    echo -e "${EfeitoCorErro}ERRO: $*${EfeitoFecha}"
    echo "Consulte o log: $LOG_FILE"
    exit 1
}

trap 'erro "Falha na linha $LINENO: $BASH_COMMAND"' ERR

info() {
    echo -e "${EfeitoCorOK}$*${EfeitoFecha}"
}

alerta() {
    echo -e "${EfeitoCorAlerta}$*${EfeitoFecha}"
}

require_root() {
    [[ $EUID -eq 0 ]] || erro "Execute este instalador como root."
}

pause_if_interactive() {
    [[ "${silenciar:-}" == "sim" ]] && return 0
    read -r -n 1 -s -p "Pressione qualquer tecla para continuar..."
    echo
}

usage() {
    echo
    echo -e "${EfeitoCorTitulo}Uso:${EfeitoFecha} $0 [--skip-inter] [--ssl]"
    echo
    echo "  --skip-inter   Desativa as pausas durante a instalação."
    echo "  --ssl          Instala/configura somente os certificados SSL."
    echo
}

install_packages() {
    info "Instalando/verificando dependências do sistema..."

    dnf -y install \
        httpd \
        mod_ssl \
        php \
        php-cli \
        php-fpm \
        php-mysqlnd \
        php-mbstring \
        php-xml \
        php-curl \
        php-zip \
        php-gd \
        php-json \
        php-opcache \
        mariadb \
        mariadb-server \
        wget \
        unzip \
        curl \
        openssl \
        git \
        cronie \
        sed \
        findutils \
        tar \
        gzip \
        java-17-openjdk \
        java-17-openjdk-devel \
        certbot

    systemctl enable --now mariadb
    systemctl enable --now httpd
    systemctl enable --now php-fpm
    systemctl enable --now crond

    command -v mysql >/dev/null || erro "mysql não encontrado."
    command -v certbot >/dev/null || erro "certbot não encontrado."
    command -v java >/dev/null || erro "Java não encontrado."
}

validate_domain() {
    local d="$1"
    [[ "$d" =~ ^[A-Za-z0-9.-]+$ ]] || erro "Domínio inválido: $d"
}

dns_check() {
    local domain="$1"
    local expected
    expected="$(getent ahostsv4 "$domain" | awk 'NR==1 {print $1}' || true)"

    if [[ -z "$expected" ]]; then
        alerta "Não foi possível resolver $domain neste momento."
        return 1
    fi

    info "DNS OK: $domain -> $expected"
}

create_user() {
    if id "$PAINEL_USER" >/dev/null 2>&1; then
        info "Usuário $PAINEL_USER já existe."
    else
        useradd -m -d "$PAINEL_HOME" -s /sbin/nologin "$PAINEL_USER"
    fi

    echo "$PAINEL_USER:$senha_ftp" | chpasswd
}

configure_database() {
    info "Configurando banco de dados..."

    mysql -u root -p"$senha_root_mysql" <<SQL
CREATE DATABASE IF NOT EXISTS \`$DB_NAME\`;
CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$senha_painel_mysql';
CREATE USER IF NOT EXISTS '$DB_USER'@'%' IDENTIFIED BY '$senha_painel_mysql';
ALTER USER '$DB_USER'@'localhost' IDENTIFIED BY '$senha_painel_mysql';
ALTER USER '$DB_USER'@'%' IDENTIFIED BY '$senha_painel_mysql';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'localhost';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'%';
FLUSH PRIVILEGES;
SQL
}

download_panel() {
    mkdir -p "$WEB_ROOT"
    cd "$WEB_ROOT"

    local zip="painel-video-2026.zip"
    local url="${dominio_source_instalador}/${zip}"

    info "Baixando painel: $url"
    curl -fL --retry 3 --connect-timeout 20 -o "$zip" "$url"

    [[ -s "$zip" ]] || erro "Arquivo do painel não foi baixado."

    unzip -oq "$zip"
    rm -f "$zip"

    [[ -f "$WEB_ROOT/banco-de-dados-video.sql" ]] || erro \
        "banco-de-dados-video.sql não encontrado após extrair o painel."

    [[ -d "$WEB_ROOT/admin" ]] || erro \
        "Diretório admin não encontrado após extrair o painel."
}

configure_php_database() {
    local file="$WEB_ROOT/admin/inc/conecta.php"

    mkdir -p "$(dirname "$file")"

    cat > "$file" <<PHP
<?php
\$host = "localhost";
\$user = "$DB_USER";
\$pass = "$senha_painel_mysql";
\$bd_streaming = "$DB_NAME";

\$conexao = mysqli_connect(\$host, \$user, \$pass, \$bd_streaming);

if (!\$conexao) {
    die("Erro ao conectar ao banco de dados.");
}

mysqli_set_charset(\$conexao, "utf8mb4");
?>
PHP
}

configure_permissions() {
    info "Configurando permissões..."

    chown -R "$PAINEL_USER:$PAINEL_USER" "$PAINEL_HOME"
    find "$PAINEL_HOME" -type d -exec chmod 755 {} \;
    find "$PAINEL_HOME" -type f -exec chmod 644 {} \;

    for dir in \
        "$WEB_ROOT/app" \
        "$WEB_ROOT/player" \
        "$WEB_ROOT/cache" \
        "$WEB_ROOT/temp"; do
        if [[ -d "$dir" ]]; then
            chmod -R u+rwX "$dir"
            chown -R "$PAINEL_USER:$PAINEL_USER" "$dir"
        fi
    done

    if [[ -f "$WEB_ROOT/robots/configurar-ssl-site-adm.sh" ]]; then
        chmod 750 "$WEB_ROOT/robots/configurar-ssl-site-adm.sh"
    fi
}

install_replace_compat() {
    if command -v replace >/dev/null 2>&1; then
        return 0
    fi

    # O instalador original dependia de "replace". A partir daqui usamos sed.
    info "Comando 'replace' não encontrado; usando sed."
}

build_apk() {
    local source_dir="$1"

    [[ -d "$source_dir" ]] || erro "Diretório Android não encontrado: $source_dir"

    rm -rf "$WEB_ROOT/app/source_pre_compilacao"
    cp -a "$source_dir" "$WEB_ROOT/app/source_pre_compilacao"

    cd "$WEB_ROOT/app/source_pre_compilacao"

    [[ -f app/build.gradle ]] || erro "app/build.gradle não encontrado em $source_dir"
    [[ -f gradlew ]] || erro "gradlew não encontrado em $source_dir"

    sed -i 's/codigo_versao/1/g' app/build.gradle
    sed -i 's/numero_versao/1.0/g' app/build.gradle

    sed -i '/HASH_GRADLEW_APP/d' gradlew
    chmod +x gradlew

    export JAVA_HOME
    JAVA_HOME="$(dirname "$(dirname "$(readlink -f "$(command -v java)")")")"
    export PATH="$JAVA_HOME/bin:$PATH"

    info "Java: $(java -version 2>&1 | head -n 1)"
    info "Compilando: $source_dir"

    ./gradlew --no-daemon assembleRelease

    cd "$WEB_ROOT"
    rm -rf "$WEB_ROOT/app/source_pre_compilacao"
}

build_apks() {
    info "Compilando aplicativos..."

    build_apk "$WEB_ROOT/app/source-app-player"
    build_apk "$WEB_ROOT/app/source-app-multiplataforma"
}

import_database() {
    info "Importando estrutura do banco..."

    mysql -u root -p"$senha_root_mysql" "$DB_NAME" < "$WEB_ROOT/banco-de-dados-video.sql"

    mysql -u root -p"$senha_root_mysql" "$DB_NAME" <<SQL
INSERT INTO administradores (codigo, nome, usuario, senha)
VALUES (NULL, 'Administrador', 'admin', PASSWORD('$senha_admin_painel'));

INSERT INTO configuracoes (dominio_padrao, codigo_servidor_atual, manutencao)
VALUES ('$dominio_painel_video', '1', 'nao');
SQL
}

configure_apache_http() {
    info "Configurando Apache HTTP..."

    cat > /etc/httpd/conf.d/video.conf <<EOF
<VirtualHost *:80>
    ServerName $dominio_painel_video
    DocumentRoot $WEB_ROOT

    <Directory $WEB_ROOT>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/video_error.log
    CustomLog /var/log/httpd/video_access.log combined
</VirtualHost>

<VirtualHost *:80>
    ServerName $dominio_painel_video_player
    DocumentRoot $WEB_ROOT/player

    <Directory $WEB_ROOT/player>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/video_player_error.log
    CustomLog /var/log/httpd/video_player_access.log combined
</VirtualHost>
EOF

    apachectl configtest
    systemctl restart httpd
}

install_certificate() {
    local domain="$1"

    info "Solicitando certificado Let's Encrypt para $domain..."

    if [[ -f "/etc/letsencrypt/live/$domain/fullchain.pem" ]] &&
       certbot certificates 2>/dev/null | grep -q "Domains:.*$domain"; then
        info "Certificado existente encontrado para $domain."
        return 0
    fi

    systemctl stop httpd

    certbot certonly \
        --standalone \
        --non-interactive \
        --agree-tos \
        --register-unsafely-without-email \
        --keep-until-expiring \
        -d "$domain"

    systemctl start httpd

    [[ -f "/etc/letsencrypt/live/$domain/fullchain.pem" ]] || \
        erro "Certificado não foi criado para $domain."
}

configure_apache_ssl() {
    info "Configurando HTTPS..."

    cat > "/etc/httpd/conf.d/$dominio_painel_video-ssl.conf" <<EOF
<VirtualHost *:443>
    ServerName $dominio_painel_video
    DocumentRoot $WEB_ROOT

    <Directory $WEB_ROOT>
        AllowOverride All
        Require all granted
    </Directory>

    SSLEngine on
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCertificateFile /etc/letsencrypt/live/$dominio_painel_video/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/$dominio_painel_video/privkey.pem

    ErrorLog /var/log/httpd/video_ssl_error.log
    CustomLog /var/log/httpd/video_ssl_access.log combined
</VirtualHost>

<VirtualHost *:443>
    ServerName $dominio_painel_video_player
    DocumentRoot $WEB_ROOT/player

    <Directory $WEB_ROOT/player>
        AllowOverride All
        Require all granted
    </Directory>

    SSLEngine on
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCertificateFile /etc/letsencrypt/live/$dominio_painel_video_player/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/$dominio_painel_video_player/privkey.pem

    ErrorLog /var/log/httpd/video_player_ssl_error.log
    CustomLog /var/log/httpd/video_player_ssl_access.log combined
</VirtualHost>
EOF

    apachectl configtest
    systemctl restart httpd
}

configure_cron() {
    info "Configurando tarefas cron..."

    local tmp
    tmp="$(mktemp)"

    crontab -l 2>/dev/null | grep -vF "$WEB_ROOT/robots/" > "$tmp" || true

    cat >> "$tmp" <<EOF
0 2 * * * /usr/bin/php $WEB_ROOT/robots/limpar-logs.php
*/30 * * * * /usr/bin/php $WEB_ROOT/robots/monitor-servidores.php
*/30 * * * * /usr/bin/php $WEB_ROOT/robots/monitor-capacidade.php
*/10 * * * * /usr/bin/php $WEB_ROOT/robots/atualizar-uso-ftp.php registros=0-20000
*/5 * * * * /usr/bin/php $WEB_ROOT/robots/gerar-estatisticas-wowza.php registros=0-20000
0 3 * * 0 /usr/bin/php $WEB_ROOT/robots/limpar-estatisticas.php
*/10 * * * * /usr/bin/php $WEB_ROOT/robots/monitor-streamings.php registros=0-20000
* * * * * /usr/bin/php -q $WEB_ROOT/robots/agendamentos.php registros=0-10000
* * * * * /usr/bin/php $WEB_ROOT/robots/agendamentos-lives.php registros=0-10000
0 1 * * * /usr/bin/php $WEB_ROOT/robots/backup-painel-mysql.php
EOF

    crontab "$tmp"
    rm -f "$tmp"
}

configure_renewal() {
    info "Configurando renovação automática do Let's Encrypt..."

    cat > /etc/cron.d/painel-video-letsencrypt <<EOF
17 3 * * * root certbot renew --quiet --deploy-hook "systemctl reload httpd"
EOF

    chmod 644 /etc/cron.d/painel-video-letsencrypt
}

print_summary() {
    echo
    echo -e "${EfeitoCorTitulo}########################################################${EfeitoFecha}"
    echo -e "${EfeitoCorOK}INSTALAÇÃO CONCLUÍDA${EfeitoFecha}"
    echo -e "${EfeitoCorTitulo}########################################################${EfeitoFecha}"
    echo
    echo -e "${EfeitoCorAlerta}URL Painel:${EfeitoFecha} https://$dominio_painel_video/admin/login"
    echo -e "${EfeitoCorAlerta}URL Player:${EfeitoFecha} https://$dominio_painel_video_player"
    echo -e "${EfeitoCorAlerta}Login:${EfeitoFecha} admin"
    echo -e "${EfeitoCorAlerta}Senha Admin:${EfeitoFecha} $senha_admin_painel"
    echo
    echo -e "${EfeitoCorAlerta}Usuário MySQL:${EfeitoFecha} $DB_USER"
    echo -e "${EfeitoCorAlerta}Senha MySQL:${EfeitoFecha} $senha_painel_mysql"
    echo -e "${EfeitoCorAlerta}Banco:${EfeitoFecha} $DB_NAME"
    echo
    echo -e "${EfeitoCorAlerta}Usuário FTP/Sistema:${EfeitoFecha} $PAINEL_USER"
    echo -e "${EfeitoCorAlerta}Senha:${EfeitoFecha} $senha_ftp"
    echo
    echo -e "${EfeitoCorAlerta}Diretório:${EfeitoFecha} $WEB_ROOT"
    echo -e "${EfeitoCorAlerta}Log:${EfeitoFecha} $LOG_FILE"
    echo
}

ssl_only() {
    require_root

    read -r -p "Domínio Video: " dominio_painel_video
    read -r -p "Domínio Player Video: " dominio_painel_video_player

    validate_domain "$dominio_painel_video"
    validate_domain "$dominio_painel_video_player"

    alerta "Verifique se os dois domínios apontam para este servidor."
    dns_check "$dominio_painel_video" || true
    dns_check "$dominio_painel_video_player" || true
    pause_if_interactive

    install_certificate "$dominio_painel_video"
    install_certificate "$dominio_painel_video_player"
    configure_apache_ssl
    configure_renewal

    info "SSL configurado com sucesso."
}

full_install() {
    require_root

    echo -e "${EfeitoCorTitulo}########################################################${EfeitoFecha}"
    echo -e "${EfeitoCorTitulo}# Instalador do Painel de Streaming de Vídeo          #${EfeitoFecha}"
    echo -e "${EfeitoCorTitulo}# Versão revisada para AlmaLinux 9                    #${EfeitoFecha}"
    echo -e "${EfeitoCorTitulo}########################################################${EfeitoFecha}"
    echo

    read -r -p "Domínio Video: " dominio_painel_video
    read -r -p "Domínio Player Video: " dominio_painel_video_player
    read -r -s -p "Senha root do MySQL/MariaDB: " senha_root_mysql
    echo

    validate_domain "$dominio_painel_video"
    validate_domain "$dominio_painel_video_player"

    echo
    echo "Painel : $dominio_painel_video"
    echo "Player : $dominio_painel_video_player"
    echo

    read -r -p "Confirma a instalação? (y/n): " confirma
    [[ "$confirma" =~ ^[Yy]$ ]] || exit 1

    pause_if_interactive

    install_packages
    create_user
    configure_database
    download_panel
    configure_php_database
    configure_permissions
    install_replace_compat

    configure_apache_http
    build_apks
    import_database
    configure_cron

    alerta "Agora será configurado o SSL."
    alerta "Os dois DNS precisam apontar para este servidor e a porta 80 precisa estar acessível."
    pause_if_interactive

    dns_check "$dominio_painel_video" || alerta "DNS do painel não resolveu."
    dns_check "$dominio_painel_video_player" || alerta "DNS do player não resolveu."

    install_certificate "$dominio_painel_video"
    install_certificate "$dominio_painel_video_player"
    configure_apache_ssl
    configure_renewal

    systemctl enable --now httpd php-fpm mariadb crond

    print_summary
}

require_root

case "${1:-}" in
    --help|-h)
        usage
        ;;
    --ssl)
        silenciar="sim"
        ssl_only
        ;;
    --skip-inter)
        silenciar="sim"
        full_install
        ;;
    "")
        full_install
        ;;
    *)
        usage
        erro "Opção desconhecida: $1"
        ;;
esac
