<?php
// playlist-converter.php
// One-file drag & drop combiner + converter for M3U/M3U8/JSON

// ---------- PHP BACKEND ----------
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    header('Content-Type: application/json; charset=utf-8');

    $targetFormat = $_POST['targetFormat'] ?? 'json';
    $allChannels = [];

    // Normalize channel structure:
    // [
    //   'name' => string,
    //   'url'  => string,
    //   'tvg_id' => string|null,
    //   'group'  => string|null,
    //   'logo'   => string|null,
    //   'extra'  => array
    // ]

    function addChannel(&$list, $ch) {
        if (empty($ch['url'])) return;
        $list[] = [
            'name'   => $ch['name']   ?? '',
            'url'    => $ch['url']    ?? '',
            'tvg_id' => $ch['tvg_id'] ?? null,
            'group'  => $ch['group']  ?? null,
            'logo'   => $ch['logo']   ?? null,
            'extra'  => $ch['extra']  ?? []
        ];
    }

    function parseM3U($content) {
        $lines = preg_split('/\r\n|\r|\n/', $content);
        $channels = [];
        $currentMeta = null;

        foreach ($lines as $line) {
            $line = trim($line);
            if ($line === '' || strpos($line, '#EXTM3U') === 0) {
                continue;
            }
            if (strpos($line, '#EXTINF:') === 0) {
                // Example: #EXTINF:-1 tvg-id="xxx" tvg-logo="..." group-title="News",Channel Name
                $meta = [
                    'name'   => '',
                    'tvg_id' => null,
                    'group'  => null,
                    'logo'   => null,
                    'extra'  => []
                ];
                $after = substr($line, 8); // after "#EXTINF:"
                // Split attributes and name by comma
                $parts = explode(',', $after, 2);
                $attrs = $parts[0] ?? '';
                $name  = $parts[1] ?? '';

                $meta['name'] = trim($name);

                // Extract attributes like tvg-id, tvg-logo, group-title
                if (preg_match_all('/(\w+?)="(.*?)"/', $attrs, $m, PREG_SET_ORDER)) {
                    foreach ($m as $match) {
                        $key = strtolower($match[1]);
                        $val = $match[2];
                        if ($key === 'tvg-id')   $meta['tvg_id'] = $val;
                        elseif ($key === 'tvg-logo') $meta['logo'] = $val;
                        elseif ($key === 'group-title') $meta['group'] = $val;
                        else $meta['extra'][$key] = $val;
                    }
                }
                $currentMeta = $meta;
            } elseif ($line[0] !== '#') {
                // URL line
                if ($currentMeta) {
                    $currentMeta['url'] = $line;
                    $channels[] = $currentMeta;
                    $currentMeta = null;
                } else {
                    // URL without EXTINF
                    $channels[] = [
                        'name'   => $line,
                        'url'    => $line,
                        'tvg_id' => null,
                        'group'  => null,
                        'logo'   => null,
                        'extra'  => []
                    ];
                }
            }
        }
        return $channels;
    }

    function parseJsonContent($content) {
        $data = json_decode($content, true);
        $channels = [];

        if (!$data) return $channels;

        // Case 1: your format { category, totalItems, items: [] }
        if (isset($data['items']) && is_array($data['items'])) {
            foreach ($data['items'] as $item) {
                $channels[] = [
                    'name'   => $item['title'] ?? '',
                    'url'    => $item['location'] ?? '',
                    'tvg_id' => $item['slug'] ?? null,
                    'group'  => $data['category'] ?? null,
                    'logo'   => $item['thumb'] ?? null,
                    'extra'  => [
                        'id'          => $item['id'] ?? null,
                        'description' => $item['description'] ?? null,
                        'tags'        => $item['tags'] ?? [],
                        'isLive'      => $item['isLive'] ?? null,
                        'format'      => $item['format'] ?? null
                    ]
                ];
            }
        }
        // Case 2: already an array of channels
        elseif (isset($data[0]) && is_array($data[0])) {
            foreach ($data as $item) {
                $channels[] = [
                    'name'   => $item['name'] ?? ($item['title'] ?? ''),
                    'url'    => $item['url']  ?? ($item['location'] ?? ''),
                    'tvg_id' => $item['tvg_id'] ?? ($item['id'] ?? null),
                    'group'  => $item['group'] ?? ($item['category'] ?? null),
                    'logo'   => $item['logo'] ?? ($item['thumb'] ?? null),
                    'extra'  => $item
                ];
            }
        }

        return $channels;
    }

    // Collect uploaded files
    if (!isset($_FILES['files'])) {
        echo json_encode(['error' => 'No files uploaded']);
        exit;
    }

    $files = $_FILES['files'];
    for ($i = 0; $i < count($files['name']); $i++) {
        if ($files['error'][$i] !== UPLOAD_ERR_OK) continue;
        $tmpName = $files['tmp_name'][$i];
        $name    = $files['name'][$i];
        $ext     = strtolower(pathinfo($name, PATHINFO_EXTENSION));
        $content = file_get_contents($tmpName);

        if (in_array($ext, ['m3u', 'm3u8'])) {
            $chs = parseM3U($content);
            foreach ($chs as $ch) addChannel($allChannels, $ch);
        } elseif ($ext === 'json') {
            $chs = parseJsonContent($content);
            foreach ($chs as $ch) addChannel($allChannels, $ch);
        }
    }

    // Deduplicate by URL
    $seen = [];
    $unique = [];
    foreach ($allChannels as $ch) {
        if (isset($seen[$ch['url']])) continue;
        $seen[$ch['url']] = true;
        $unique[] = $ch;
    }
    $allChannels = $unique;

    // Output in requested format
    if ($targetFormat === 'm3u') {
        $lines = ["#EXTM3U"];
        foreach ($allChannels as $ch) {
            $attrs = [];
            if ($ch['tvg_id']) $attrs[] = 'tvg-id="' . addslashes($ch['tvg_id']) . '"';
            if ($ch['logo'])   $attrs[] = 'tvg-logo="' . addslashes($ch['logo']) . '"';
            if ($ch['group'])  $attrs[] = 'group-title="' . addslashes($ch['group']) . '"';
            $attrStr = implode(' ', $attrs);
            $name = $ch['name'] ?: $ch['url'];
            $lines[] = '#EXTINF:-1 ' . $attrStr . ',' . $name;
            $lines[] = $ch['url'];
        }
        echo json_encode([
            'format' => 'm3u',
            'content'=> implode("\n", $lines),
            'count'  => count($allChannels)
        ]);
    } else {
        echo json_encode([
            'format' => 'json',
            'items'  => $allChannels,
            'count'  => count($allChannels)
        ]);
    }
    exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Playlist Combiner & Converter</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
  body {
    margin: 0;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    background: #05060a;
    color: #f5f5f5;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
  }
  .shell {
    background: #10121a;
    border-radius: 16px;
    padding: 20px;
    max-width: 640px;
    width: 100%;
    box-shadow: 0 18px 40px rgba(0,0,0,0.7);
  }
  h1 {
    margin-top: 0;
    font-size: 20px;
  }
  .dropzone {
    border: 2px dashed rgba(255,255,255,0.3);
    border-radius: 12px;
    padding: 30px;
    text-align: center;
    cursor: pointer;
    background: rgba(0,0,0,0.4);
  }
  .dropzone.dragover {
    border-color: #e50914;
    background: rgba(229,9,20,0.1);
  }
  .small {
    font-size: 12px;
    color: #aaa;
  }
  .controls {
    margin-top: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
  }
  select, button {
    border-radius: 999px;
    border: none;
    padding: 6px 12px;
    font-size: 13px;
  }
  button {
    background: #e50914;
    color: #fff;
    cursor: pointer;
  }
  button:disabled {
    opacity: 0.5;
    cursor: default;
  }
  textarea {
    width: 100%;
    height: 220px;
    margin-top: 12px;
    border-radius: 8px;
    border: none;
    padding: 8px;
    font-family: monospace;
    font-size: 12px;
    background: #05060a;
    color: #f5f5f5;
    resize: vertical;
  }
</style>
</head>
<body>
<div class="shell">
  <h1>Playlist Combiner & Converter</h1>
  <div id="dropzone" class="dropzone">
    <div>Drop <b>.m3u</b>, <b>.m3u8</b>, or <b>.json</b> files here</div>
    <div class="small">or click to browse</div>
    <input id="fileInput" type="file" multiple accept=".m3u,.m3u8,.json" style="display:none;">
  </div>

  <div class="controls">
    <div>
      <span class="small">Output format:</span>
      <select id="targetFormat">
        <option value="json">JSON</option>
        <option value="m3u">M3U</option>
      </select>
    </div>
    <button id="convertBtn" disabled>Combine & Convert</button>
  </div>

  <textarea id="output" placeholder="Combined output will appear here..." readonly></textarea>
</div>

<script>
const dropzone   = document.getElementById('dropzone');
const fileInput  = document.getElementById('fileInput');
const convertBtn = document.getElementById('convertBtn');
const output     = document.getElementById('output');
const targetFormat = document.getElementById('targetFormat');

let selectedFiles = [];

dropzone.addEventListener('click', () => fileInput.click());

fileInput.addEventListener('change', () => {
  selectedFiles = Array.from(fileInput.files);
  updateState();
});

dropzone.addEventListener('dragover', e => {
  e.preventDefault();
  dropzone.classList.add('dragover');
});
dropzone.addEventListener('dragleave', e => {
  e.preventDefault();
  dropzone.classList.remove('dragover');
});
dropzone.addEventListener('drop', e => {
  e.preventDefault();
  dropzone.classList.remove('dragover');
  const files = Array.from(e.dataTransfer.files);
  selectedFiles = selectedFiles.concat(files);
  updateState();
});

function updateState() {
  if (selectedFiles.length) {
    dropzone.querySelector('div').innerHTML =
      selectedFiles.length + ' file(s) selected';
    convertBtn.disabled = false;
  } else {
    dropzone.querySelector('div').innerHTML =
      'Drop <b>.m3u</b>, <b>.m3u8</b>, or <b>.json</b> files here';
    convertBtn.disabled = true;
  }
}

convertBtn.addEventListener('click', async () => {
  if (!selectedFiles.length) return;
  convertBtn.disabled = true;
  convertBtn.textContent = 'Processing...';

  const formData = new FormData();
  selectedFiles.forEach(f => formData.append('files[]', f));
  formData.append('targetFormat', targetFormat.value);

  try {
    const res = await fetch(location.href, {
      method: 'POST',
      body: formData
    });
    const data = await res.json();
    if (data.error) {
      output.value = 'Error: ' + data.error;
    } else {
      output.value = data.content || JSON.stringify(data, null, 2);
    }
  } catch (e) {
    output.value = 'Error: ' + e;
  } finally {
    convertBtn.disabled = false;
    convertBtn.textContent = 'Combine & Convert';
  }
});
</script>
</body>
</html>