<?php
/**
 * Kontroler Zmiana DNS - masowa zmiana adresów URL w playlistach
 */

require_once __DIR__ . '/BaseController.php';

class DnsController extends BaseController
{
    private Playlist $playlistModel;
    private User $userModel;
    private Database $db;

    public function __construct()
    {
        parent::__construct();
        $this->playlistModel = new Playlist();
        $this->userModel = new User();
        $this->db = Database::getInstance();
    }

    /**
     * Strona główna - formularz zmiany DNS
     */
    public function index(): void
    {
        $users = [];
        if ($this->auth->isAdmin()) {
            $users = $this->userModel->getAll(1000);
        }

        $this->render('dns/index.tpl', [
            'pageTitle' => 'Zmiana DNS',
            'users' => $users
        ]);
    }

    /**
     * Wykonaj zmianę DNS
     */
    public function replace(): void
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            $this->redirect('dns');
            return;
        }

        if (!$this->verifyCsrf()) {
            return;
        }

        $oldAddress = trim(post('old_address', ''));
        $newAddress = trim(post('new_address', ''));
        $targetUser = post('target_user', 'self'); // 'self', 'all', lub ID użytkownika

        // Walidacja
        if (empty($oldAddress)) {
            $this->renderWithError('Stary adres jest wymagany.');
            return;
        }

        if (empty($newAddress)) {
            $this->renderWithError('Nowy adres jest wymagany.');
            return;
        }

        if ($oldAddress === $newAddress) {
            $this->renderWithError('Stary i nowy adres są identyczne.');
            return;
        }

        // Określ zakres użytkowników
        $userIds = $this->getTargetUserIds($targetUser);
        
        if (empty($userIds)) {
            $this->renderWithError('Nie znaleziono użytkowników do aktualizacji.');
            return;
        }

        // Wykonaj zamianę
        $result = $this->performReplace($oldAddress, $newAddress, $userIds);

        // Loguj akcję
        $targetDesc = $this->getTargetDescription($targetUser);
        $this->logger->log(
            'dns_replaced',
            "Zmiana DNS: '{$oldAddress}' -> '{$newAddress}', zakres: {$targetDesc}, zaktualizowano: {$result['updated']} playlist",
            $this->currentUser['id']
        );

        if (isAjax()) {
            $this->json([
                'success' => true,
                'updated' => $result['updated'],
                'message' => "Zaktualizowano {$result['updated']} playlist."
            ]);
        } else {
            $this->redirect('dns', 'success', "Zaktualizowano {$result['updated']} playlist.");
        }
    }

    /**
     * Pobierz ID użytkowników do aktualizacji
     */
    private function getTargetUserIds(string $targetUser): array
    {
        if (!$this->auth->isAdmin()) {
            // Zwykły użytkownik - tylko swoje
            return [$this->currentUser['id']];
        }

        if ($targetUser === 'self') {
            return [$this->currentUser['id']];
        }

        if ($targetUser === 'all') {
            $users = $this->userModel->getAll(10000);
            return array_column($users, 'id');
        }

        // Konkretny użytkownik
        $userId = (int)$targetUser;
        if ($userId > 0) {
            return [$userId];
        }

        return [];
    }

    /**
     * Wykonaj zamianę adresów w playlistach
     */
    private function performReplace(string $oldAddress, string $newAddress, array $userIds): array
    {
        $updated = 0;
        $now = time();

        // Pobierz wszystkie playlisty dla wskazanych użytkowników
        $placeholders = implode(',', array_fill(0, count($userIds), '?'));
        
        $playlists = $this->db->fetchAll(
            "SELECT p.id, p.type, p.config_json 
             FROM playlists p
             JOIN devices d ON p.device_id = d.id
             WHERE d.user_id IN ({$placeholders})",
            $userIds
        );

        foreach ($playlists as $playlist) {
            $config = json_decode($playlist['config_json'], true);
            $modified = false;

            // Sprawdź i zamień w zależności od typu
            switch ($playlist['type']) {
                case 'xtream':
                    if (isset($config['host']) && strpos($config['host'], $oldAddress) !== false) {
                        $config['host'] = str_replace($oldAddress, $newAddress, $config['host']);
                        $modified = true;
                    }
                    break;

                case 'm3u':
                    if (isset($config['url']) && strpos($config['url'], $oldAddress) !== false) {
                        $config['url'] = str_replace($oldAddress, $newAddress, $config['url']);
                        $modified = true;
                    }
                    if (isset($config['epg_link']) && strpos($config['epg_link'], $oldAddress) !== false) {
                        $config['epg_link'] = str_replace($oldAddress, $newAddress, $config['epg_link']);
                        $modified = true;
                    }
                    break;

                case 'stalker':
                    if (isset($config['server_url']) && strpos($config['server_url'], $oldAddress) !== false) {
                        $config['server_url'] = str_replace($oldAddress, $newAddress, $config['server_url']);
                        $modified = true;
                    }
                    if (isset($config['referrer_url']) && strpos($config['referrer_url'], $oldAddress) !== false) {
                        $config['referrer_url'] = str_replace($oldAddress, $newAddress, $config['referrer_url']);
                        $modified = true;
                    }
                    if (isset($config['epg_link']) && strpos($config['epg_link'], $oldAddress) !== false) {
                        $config['epg_link'] = str_replace($oldAddress, $newAddress, $config['epg_link']);
                        $modified = true;
                    }
                    break;
            }

            // Zapisz jeśli zmodyfikowano
            if ($modified) {
                $newConfigJson = json_encode($config, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
                
                $this->db->execute(
                    "UPDATE playlists SET config_json = :config, update_date = :update_date, updated_at = datetime('now') WHERE id = :id",
                    [
                        'config' => $newConfigJson,
                        'update_date' => $now,
                        'id' => $playlist['id']
                    ]
                );
                
                $updated++;
            }
        }

        return ['updated' => $updated];
    }

    /**
     * Opis zakresu dla logów
     */
    private function getTargetDescription(string $targetUser): string
    {
        if ($targetUser === 'self') {
            return 'własne playlisty';
        }
        if ($targetUser === 'all') {
            return 'wszyscy użytkownicy';
        }
        
        $user = $this->userModel->getById((int)$targetUser);
        return $user ? "użytkownik: {$user['username']}" : "użytkownik ID: {$targetUser}";
    }

    /**
     * Renderuj formularz z błędem
     */
    private function renderWithError(string $error): void
    {
        $users = [];
        if ($this->auth->isAdmin()) {
            $users = $this->userModel->getAll(1000);
        }

        if (isAjax()) {
            $this->json(['success' => false, 'error' => $error]);
        } else {
            $this->render('dns/index.tpl', [
                'pageTitle' => 'Zmiana DNS',
                'users' => $users,
                'error' => $error,
                'old_address' => post('old_address', ''),
                'new_address' => post('new_address', ''),
                'target_user' => post('target_user', 'self')
            ]);
        }
    }
}
