<?php
// ARQUIVO: api/importer.php
// LOCAL: Pasta api/ (public_html/api/importer.php)

set_time_limit(0);
ini_set('memory_limit', '-1');
header('Content-Type: application/json');
session_start();
require_once '../includes/db.php';

// === CONFIGURAÇÃO TMDB ===
$tmdb_key = "f99aa9ae1fe7619969cc7db0938c1ae5"; 
try {
    $stmt = $pdo->query("SELECT tmdb_api_key FROM configuracoes LIMIT 1");
    $k = $stmt->fetchColumn();
    if($k) $tmdb_key = $k;
} catch(Exception $e){}

// --- FUNÇÕES ---

// Função auxiliar para extrair Série, Temporada e Episódio
function parseEpisodeInfo($fullname) {
    // Tenta padrões comuns: S01E01, S01 E01, 1x01, Season 1 Episode 1
    $patterns = [
        '/(.*?)[\. ]S(\d{1,2})[ \.]?E(\d{1,4})/i',  // Ex: Breaking Bad S01 E01
        '/(.*?)[\. ](\d{1,2})x(\d{1,4})/i',         // Ex: Breaking Bad 1x01
    ];

    foreach ($patterns as $pattern) {
        if (preg_match($pattern, $fullname, $matches)) {
            return [
                'show_name' => trim(str_replace(['.', '_', '-'], ' ', $matches[1])), // Nome Limpo da Série
                'season'    => (int)$matches[2],
                'episode'   => (int)$matches[3],
                'full_match'=> true
            ];
        }
    }
    
    // Se não achar padrão, retorna como se fosse tudo nome da série (fallback)
    return [
        'show_name' => trim($fullname),
        'season'    => 0, // Temporada "Extras" ou desconhecida
        'episode'   => 0,
        'full_match'=> false
    ];
}

function searchTMDB($query, $type, $key) {
    if(strlen($query) < 2) return null;
    $query = urlencode($query);
    $url = "https://api.themoviedb.org/3/search/$type?api_key=$key&language=pt-BR&query=$query&page=1";
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 2); 
    $res = curl_exec($ch);
    curl_close($ch);
    
    $json = json_decode($res, true);
    if(!empty($json['results'][0])) {
        $r = $json['results'][0];
        $img_base = 'https://image.tmdb.org/t/p/w500';
        return [
            'cover' => $r['poster_path'] ? $img_base.$r['poster_path'] : ($r['backdrop_path'] ? $img_base.$r['backdrop_path'] : ''),
            'plot' => $r['overview'] ?? '',
            'year' => substr($r['release_date'] ?? $r['first_air_date'] ?? '', 0, 4),
            'rating' => $r['vote_average'] ?? 0,
            'id' => $r['id'] // ID do TMDB para buscar detalhes extras se precisar
        ];
    }
    return null;
}

function cleanName($name) {
    $name = preg_replace('/[\(\[\{].*?[\)\]\}]/', '', $name);
    $name = str_replace(['MKV', 'MP4', 'AVI', 'FHD', 'HD', 'SD', '4K', 'H265', 'LEG', 'DUB', 'Dual'], '', $name);
    $name = str_replace(['-', '.', '_'], ' ', $name);
    return trim($name);
}

// === NOVA FUNÇÃO PARA ATUALIZAR OS BOUQUETS AUTOMATICAMENTE ===
function updateBouquets($pdo, $bouquets, $new_cat_ids) {
    if (empty($bouquets)) return;
    
    foreach ($bouquets as $bq_id) {
        $stmt = $pdo->prepare("SELECT bouq_channels, bouq_movies, bouq_series FROM bouquets WHERE id = ?");
        $stmt->execute([$bq_id]);
        $bq = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($bq) {
            $ch = json_decode($bq['bouq_channels'] ?? '[]', true);
            $mv = json_decode($bq['bouq_movies'] ?? '[]', true);
            $sr = json_decode($bq['bouq_series'] ?? '[]', true);
            $changed = false;
            
            // Adiciona novas categorias de canais
            if(!empty($new_cat_ids['channel'])) {
                foreach(array_unique($new_cat_ids['channel']) as $id) {
                    if(!in_array((string)$id, $ch) && !in_array((int)$id, $ch)) { $ch[] = (string)$id; $changed = true; }
                }
            }
            // Adiciona novas categorias de filmes
            if(!empty($new_cat_ids['movie'])) {
                foreach(array_unique($new_cat_ids['movie']) as $id) {
                    if(!in_array((string)$id, $mv) && !in_array((int)$id, $mv)) { $mv[] = (string)$id; $changed = true; }
                }
            }
            // Adiciona novas categorias de séries
            if(!empty($new_cat_ids['series'])) {
                foreach(array_unique($new_cat_ids['series']) as $id) {
                    if(!in_array((string)$id, $sr) && !in_array((int)$id, $sr)) { $sr[] = (string)$id; $changed = true; }
                }
            }
            
            // Se houve mudança, salva no banco
            if ($changed) {
                $pdo->prepare("UPDATE bouquets SET bouq_channels=?, bouq_movies=?, bouq_series=? WHERE id=?")
                    ->execute([json_encode(array_values($ch)), json_encode(array_values($mv)), json_encode(array_values($sr)), $bq_id]);
            }
        }
    }
}

$action = $_POST['action'] ?? '';
$temp_file = '../temp_playlist.m3u';

// 1. BAIXAR URL
if ($action == 'download_url') {
    $url = $_POST['url'];
    if (!filter_var($url, FILTER_VALIDATE_URL)) { echo json_encode(['status'=>false, 'msg'=>'URL inválida.']); exit; }

    $fp = fopen($temp_file, 'w+');
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_TIMEOUT, 600);
    curl_setopt($ch, CURLOPT_FILE, $fp); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0');
    $exec = curl_exec($ch);
    curl_close($ch);
    fclose($fp);

    if (!$exec || filesize($temp_file) < 100) { echo json_encode(['status'=>false, 'msg'=>'Erro ao baixar.']); exit; }
    processCategories($temp_file);
}

// 2. UPLOAD
if ($action == 'upload_file') {
    if (!move_uploaded_file($_FILES['file']['tmp_name'], $temp_file)) { echo json_encode(['status'=>false, 'msg'=>'Erro upload.']); exit; }
    processCategories($temp_file);
}

// 3. ANALISAR CATEGORIAS (REGRAS CORRIGIDAS)
function processCategories($file) {
    if (!file_exists($file)) { echo json_encode(['status'=>false, 'msg'=>'Arquivo sumiu.']); exit; }
    $handle = fopen($file, "r");
    $categories = [];
    if ($handle) {
        while (($line = fgets($handle)) !== false) {
            if (preg_match('/group-title=["\'](.*?)["\']/i', $line, $matches)) {
                $cat_name = trim($matches[1]); 
                if(empty($cat_name)) $cat_name = "Sem Categoria";

                $type = 'channel'; // Padrão
                $lower = mb_strtolower($cat_name, 'UTF-8');

                // REGRA 1: Checa por Filmes
                if (preg_match('/(filme|movie|vod|4k|cinema|documentario|documentário|lançamento|adulto|xxx)/i', $lower)) {
                    $type = 'movie';
                }
                
                // REGRA 2: Checa por Séries
                if (preg_match('/(serie|série|novela|season|temporada|programa|private)/i', $lower)) {
                    $type = 'series';
                }

                // REGRA 3: Checa por Canais (PRIORIDADE MÁXIMA)
                if (preg_match('/(canais|canal|tv |ao vivo|live|24h)/i', $lower)) {
                    $type = 'channel';
                    
                    // Exceção estrita: Se tiver "Programa" ou "Série", e NÃO tiver a palavra "Canais" ou "Canal", volta pra Série.
                    // Isso protege "Programas de TV" mas deixa "Canais | Filmes e Séries" como Canal.
                    if (preg_match('/(programa|serie|série)/i', $lower) && !preg_match('/(canais|canal)/i', $lower)) {
                        $type = 'series';
                    }
                }

                if (!isset($categories[$cat_name])) {
                    $categories[$cat_name] = ['name' => $cat_name, 'type' => $type, 'count' => 0, 'id' => md5($cat_name)];
                }
                $categories[$cat_name]['count']++;
            }
        }
        fclose($handle);
    }
    echo json_encode(['status'=>true, 'msg'=>'Lista analisada!', 'categories'=>array_values($categories)]); exit;
}

// 4. IMPORTAÇÃO EM LOTES COM INTEGRAÇÃO DE BOUQUETS
if ($action == 'import_batch') {
    $cats_to_import = json_decode($_POST['categories'], true); 
    // Captura os bouquets selecionados na tela anterior
    $selected_bouquets = isset($_POST['bouquets']) ? json_decode($_POST['bouquets'], true) : [];
    
    $offset = (int)$_POST['offset']; 
    $limit = 100; // Reduzi o limite pois séries fazem mais queries SQL
    
    if(!file_exists($temp_file)) { echo json_encode(['status'=>false, 'msg'=>'Arquivo expirou.']); exit; }
    
    $handle = fopen($temp_file, "r");
    $count = 0; 
    $processed = 0; 
    $imported_list = []; 
    
    // Array para guardar os IDs das categorias para injetar nos bouquets
    $cats_for_bouquets = ['channel' => [], 'movie' => [], 'series' => []];
    
    $current_group = ''; $current_logo = ''; $current_name = '';
    
    while (($line = fgets($handle)) !== false) {
        $line = trim($line);
        if(empty($line)) continue;

        if(strpos($line, '#EXTINF') === 0) {
            preg_match('/group-title=["\'](.*?)["\']/i', $line, $g);
            $current_group = isset($g[1]) ? trim($g[1]) : 'Sem Categoria';
            
            $is_target = false;
            $current_type = 'channel';
            
            foreach($cats_to_import as $c) {
                if($c['name'] === $current_group) { 
                    $is_target = true; 
                    $current_type = $c['type'];
                    break; 
                }
            }

            if($is_target) {
                $count++;
                // Pular linhas já processadas
                if($count <= $offset) {
                     fgets($handle); 
                     continue;
                }
                
                // Limite por lote
                if($processed >= $limit) {
                    fclose($handle);
                    // Atualiza os bouquets antes de pausar o script
                    updateBouquets($pdo, $selected_bouquets, $cats_for_bouquets);
                    
                    echo json_encode([
                        'status'=>true, 
                        'finished'=>false, 
                        'offset'=>$offset + $processed, 
                        'processed'=>$processed, 
                        'imported_list' => $imported_list,
                        'msg' => "Salvos +$processed itens..."
                    ]);
                    exit;
                }

                preg_match('/tvg-logo=["\'](.*?)["\']/i', $line, $l);
                $current_logo = $l[1] ?? '';
                
                // Pegar nome limpo da linha M3U
                $parts = explode(',', $line);
                $raw_name = trim(end($parts));
                
                $url = trim(fgets($handle)); 
                
                // --- INSERÇÃO ---
                try {
                    // 1. Obter/Criar Categoria no DB
                    $stmt = $pdo->prepare("SELECT id FROM categories WHERE name = ? AND type = ?");
                    $stmt->execute([$current_group, $current_type]);
                    $cat_id = $stmt->fetchColumn();
                    
                    if(!$cat_id) {
                        $pdo->prepare("INSERT INTO categories (name, type) VALUES (?, ?)")->execute([$current_group, $current_type]);
                        $cat_id = $pdo->lastInsertId();
                    }
                    
                    // Adiciona o ID da categoria atual na lista para registrar no Bouquet
                    $cats_for_bouquets[$current_type][] = $cat_id;

                    // --- CANAIS ---
                    if($current_type == 'channel') {
                        $pdo->prepare("INSERT INTO channels (name, stream_url, category_id, logo_url) VALUES (?, ?, ?, ?)")
                            ->execute([$raw_name, $url, $cat_id, $current_logo]);
                        
                        $imported_list[] = ['type'=>'channel', 'category'=>$current_group, 'name'=>$raw_name];
                        $processed++;
                    } 
                    
                    // --- FILMES ---
                    elseif($current_type == 'movie') {
                        // Busca TMDB se não tiver logo ou descrição
                        $tmdb_data = searchTMDB(cleanName($raw_name), 'movie', $tmdb_key);
                        $plot = $tmdb_data['plot'] ?? "Sinopse não disponível";
                        $cover = (!empty($tmdb_data['cover'])) ? $tmdb_data['cover'] : $current_logo;
                        
                        $pdo->prepare("INSERT INTO movies (name, stream_url, category_id, cover_url, description) VALUES (?, ?, ?, ?, ?)")
                            ->execute([$raw_name, $url, $cat_id, $cover, $plot]);
                            
                        $imported_list[] = ['type'=>'movie', 'category'=>$current_group, 'name'=>$raw_name, 'year'=>($tmdb_data['year']??'')];
                        $processed++;
                    } 
                    
                    // --- SÉRIES ---
                    elseif($current_type == 'series') {
                        // 1. Parsear o nome para separar Série da Temporada/Episódio
                        $info = parseEpisodeInfo($raw_name); 
                        $series_name = $info['show_name'];
                        
                        if(empty($series_name)) $series_name = $raw_name;

                        // 2. Verificar se a SÉRIE já existe no banco
                        $stmt_s = $pdo->prepare("SELECT id, cover_url FROM series WHERE name = ? LIMIT 1");
                        $stmt_s->execute([$series_name]);
                        $series_row = $stmt_s->fetch(PDO::FETCH_ASSOC);
                        
                        $series_id = null;
                        
                        if($series_row) {
                            $series_id = $series_row['id'];
                            // Se a série já existe mas não temos capa e agora achamos uma logo no m3u, podemos atualizar (opcional)
                            if(empty($series_row['cover_url']) && !empty($current_logo)) {
                                $pdo->prepare("UPDATE series SET cover_url = ? WHERE id = ?")->execute([$current_logo, $series_id]);
                            }
                        } else {
                            // Criar Nova Série
                            $tmdb_data = searchTMDB($series_name, 'tv', $tmdb_key);
                            $s_plot = $tmdb_data['plot'] ?? "Sinopse da série...";
                            $s_cover = (!empty($tmdb_data['cover'])) ? $tmdb_data['cover'] : $current_logo;
                            
                            $stmt_ins = $pdo->prepare("INSERT INTO series (name, category_id, cover_url, description) VALUES (?, ?, ?, ?)");
                            $stmt_ins->execute([$series_name, $cat_id, $s_cover, $s_plot]);
                            $series_id = $pdo->lastInsertId();
                        }

                        // 3. Verificar se a TEMPORADA já existe
                        $season_num = $info['season'] > 0 ? $info['season'] : 1;
                        $season_name = "Temporada " . $season_num;
                        
                        $stmt_se = $pdo->prepare("SELECT id FROM seasons WHERE series_id = ? AND name = ? LIMIT 1");
                        $stmt_se->execute([$series_id, $season_name]);
                        $season_id = $stmt_se->fetchColumn();
                        
                        if(!$season_id) {
                            $pdo->prepare("INSERT INTO seasons (series_id, name) VALUES (?, ?)")
                                ->execute([$series_id, $season_name]);
                            $season_id = $pdo->lastInsertId();
                        }

                        // 4. Inserir o EPISÓDIO
                        // Formata o nome do episódio: "E05 - Nome Completo" ou apenas o nome da linha se falhar o parse
                        $ep_name = $info['full_match'] ? "E".str_pad($info['episode'], 2, '0', STR_PAD_LEFT) : $raw_name;
                        
                        // Verifica duplicação de episódio (mesmo nome na mesma temporada)
                        $stmt_check_ep = $pdo->prepare("SELECT id FROM episodes WHERE season_id = ? AND name = ? LIMIT 1");
                        $stmt_check_ep->execute([$season_id, $ep_name]);
                        
                        if(!$stmt_check_ep->fetchColumn()) {
                            $pdo->prepare("INSERT INTO episodes (season_id, name, stream_url, cover_url) VALUES (?, ?, ?, ?)")
                                ->execute([$season_id, $ep_name, $url, $current_logo]);
                        }

                        $imported_list[] = ['type'=>'series', 'category'=>$current_group, 'name'=>"$series_name (S{$season_num}E{$info['episode']})"];
                        $processed++;
                    }

                } catch(Exception $e) {
                    // Erro silencioso para não parar o loop
                }
            }
        }
    }
    
    fclose($handle);
    
    // Atualiza os bouquets no último lote
    updateBouquets($pdo, $selected_bouquets, $cats_for_bouquets);
    
    echo json_encode([
        'status'=>true, 
        'finished'=>true, 
        'offset'=>$offset + $processed, 
        'processed'=>$processed, 
        'imported_list' => $imported_list, 
        'msg' => "Concluído! Total processado: " . ($offset + $processed)
    ]);
}
?>
