#!/bin/bash

# =====================================
# Media CMS Auto Setup Script
# =====================================

PROJECT="media-cms"

echo "Creating project folder..."
mkdir -p $PROJECT/public/uploads
cd $PROJECT

# =====================================
# Initialize Node Project
# =====================================

echo "Initializing Node.js project..."
npm init -y

# =====================================
# Install Dependencies
# =====================================

echo "Installing dependencies..."
npm install express multer fs-extra cors bcrypt jsonwebtoken

# =====================================
# Create data.json
# =====================================

cat > data.json << 'EOF'
{
  "categories": []
}
EOF

# =====================================
# Create server.js
# =====================================

cat > server.js << 'EOF'
const express = require("express");
const multer = require("multer");
const fs = require("fs-extra");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcrypt");
const cors = require("cors");

const app = express();
app.use(cors());
app.use(express.json());
app.use(express.static("public"));

const SECRET = "supersecretkey";
const DATA_FILE = "data.json";

const adminUser = {
  username: "admin",
  password: bcrypt.hashSync("123456", 10)
};

const storage = multer.diskStorage({
  destination: (req, file, cb) => cb(null, "public/uploads/"),
  filename: (req, file, cb) => cb(null, Date.now() + "-" + file.originalname)
});

const upload = multer({
  storage,
  limits: { fileSize: 50 * 1024 * 1024 },
  fileFilter: (req, file, cb) => {
    if (
      file.mimetype.startsWith("image") ||
      file.mimetype.startsWith("video")
    ) {
      cb(null, true);
    } else {
      cb(new Error("Invalid file type"));
    }
  }
});

async function readData() {
  return fs.readJson(DATA_FILE);
}

async function writeData(data) {
  await fs.writeJson(DATA_FILE, data, { spaces: 2 });
}

app.post("/api/login", async (req, res) => {
  const { username, password } = req.body;

  if (username !== adminUser.username) {
    return res.sendStatus(401);
  }

  const valid = await bcrypt.compare(password, adminUser.password);
  if (!valid) return res.sendStatus(401);

  const token = jwt.sign({ username }, SECRET, { expiresIn: "2h" });
  res.json({ token });
});

function auth(req, res, next) {
  const header = req.headers.authorization;
  if (!header) return res.sendStatus(401);

  const token = header.split(" ")[1];

  jwt.verify(token, SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
}

app.get("/api/data", async (req, res) => {
  const data = await readData();
  res.json(data);
});

app.post("/api/category", auth, async (req, res) => {
  const { id, name } = req.body;

  const data = await readData();

  data.categories.push({
    id,
    name,
    items: []
  });

  await writeData(data);

  res.json({ success: true });
});

app.post("/api/upload", auth, upload.single("file"), async (req, res) => {
  const { categoryId, type } = req.body;

  const data = await readData();

  const category = data.categories.find(c => c.id === categoryId);
  if (!category) return res.sendStatus(400);

  const filePath = `/uploads/${req.file.filename}`;

  category.items.push({
    id: Date.now(),
    type,
    thumbnail: filePath,
    full: filePath
  });

  await writeData(data);

  res.json({ success: true });
});

app.listen(3000, () => {
  console.log("Server running at http://localhost:3000");
});
EOF

# =====================================
# Create public/login.html
# =====================================

cat > public/login.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>Login</title>
</head>
<body>
  <h2>Admin Login</h2>

  <input id="u" placeholder="Username">
  <input id="p" type="password" placeholder="Password">
  <button onclick="login()">Login</button>

  <script>
    async function login() {
      const res = await fetch('/api/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          username: u.value,
          password: p.value
        })
      });

      if (!res.ok) {
        alert('Login Failed');
        return;
      }

      const data = await res.json();
      localStorage.setItem('token', data.token);
      location.href = '/admin.html';
    }
  </script>
</body>
</html>
EOF

# =====================================
# Create public/admin.html
# =====================================

cat > public/admin.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
  <title>Admin Dashboard</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>

<div class="layout">

<aside class="sidebar">
  <h2>CMS</h2>
  <ul>
    <li onclick="show('dashboard')">Dashboard</li>
    <li onclick="show('media')">Media</li>
    <li onclick="show('categories')">Categories</li>
    <li onclick="logout()">Logout</li>
  </ul>
</aside>

<main class="content">

<section id="dashboard">
  <h1>Dashboard</h1>
</section>

<section id="media" class="hidden">
  <h1>Media</h1>

  <select id="categoryFilter"></select>

  <div id="dropZone" class="drop-zone">
    Drag & Drop files here
    <input type="file" id="fileInput" multiple hidden>
  </div>

  <div id="mediaGrid" class="grid"></div>
</section>

<section id="categories" class="hidden">
  <input id="cid" placeholder="Category ID">
  <input id="cname" placeholder="Category Name">
  <button onclick="addCat()">Add</button>
</section>

</main>
</div>

<script src="admin.js"></script>
</body>
</html>
EOF

# =====================================
# Create public/admin.js
# =====================================

cat > public/admin.js << 'EOF'
const token = localStorage.getItem("token");
if (!token) location.href = "/login.html";

let data = [];

function show(id){
  document.querySelectorAll("section").forEach(s=>s.classList.add("hidden"));
  document.getElementById(id).classList.remove("hidden");
}

async function load(){
  const res = await fetch("/api/data");
  data = await res.json();

  const filter = document.getElementById("categoryFilter");
  filter.innerHTML = "";

  data.categories.forEach(c=>{
    const opt = document.createElement("option");
    opt.value = c.id;
    opt.textContent = c.name;
    filter.appendChild(opt);
  });
}

async function addCat(){
  await fetch('/api/category', {
    method:'POST',
    headers:{
      'Content-Type':'application/json',
      'Authorization':'Bearer ' + token
    },
    body:JSON.stringify({
      id:cid.value,
      name:cname.value
    })
  });

  load();
}

const dz = document.getElementById('dropZone');
const fi = document.getElementById('fileInput');

dz.onclick = () => fi.click();

dz.ondragover = e => {
  e.preventDefault();
  dz.classList.add('dragover');
};

dz.ondragleave = () => dz.classList.remove('dragover');

dz.ondrop = e => {
  e.preventDefault();
  dz.classList.remove('dragover');
  uploadFiles(e.dataTransfer.files);
};

fi.onchange = () => uploadFiles(fi.files);

async function uploadFiles(files){
  const cat = document.getElementById('categoryFilter').value;

  for(let f of files){
    const form = new FormData();

    form.append('file', f);
    form.append('categoryId', cat);
    form.append('type', f.type.startsWith('video') ? 'video' : 'image');

    await fetch('/api/upload', {
      method:'POST',
      headers:{
        'Authorization':'Bearer ' + token
      },
      body:form
    });
  }

  alert('Upload Complete');
}

function logout(){
  localStorage.removeItem('token');
  location.href = '/login.html';
}

load();
EOF

# =====================================
# Create public/styles.css
# =====================================

cat > public/styles.css << 'EOF'
body {
  margin: 0;
  font-family: Arial, sans-serif;
}

.layout {
  display: flex;
  height: 100vh;
}

.sidebar {
  width: 220px;
  background: #111;
  color: white;
  padding: 20px;
}

.sidebar li {
  padding: 10px;
  cursor: pointer;
}

.content {
  flex: 1;
  padding: 20px;
}

.hidden {
  display: none;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

.drop-zone {
  border: 2px dashed #aaa;
  padding: 40px;
  text-align: center;
  margin: 20px 0;
  cursor: pointer;
}

.drop-zone.dragover {
  background: #e3f2fd;
}
EOF

# =====================================
# Finished
# =====================================

echo "====================================="
echo "Setup Complete"
echo "====================================="
echo "Run the following commands:"
echo "cd $PROJECT"
echo "node server.js"
echo ""
echo "Open in browser:"
echo "http://localhost:3000/login.html"
echo ""
echo "Default Login:"
echo "Username: admin"
echo "Password: 123456"
