import express, { Request, Response } from "express";
import Shortify from "../src";
import dotenv from "dotenv";

// Load environment variables
dotenv.config();

// Create Express app
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Create Shortify instance
const shortify = new Shortify(
  process.env.BASE_URL || "http://localhost:3000/",
  process.env.MONGODB_URI || "mongodb://localhost:27017/shortify"
);

// Connect to database before starting server
async function startServer() {
  try {
    // Connect to MongoDB
    await shortify.connect();
    console.log("Connected to MongoDB");

    // Set up routes

    // Home page - Simple form to create shortened URLs
    app.get("/", (req, res) => {
      res.send(`
        <html>
          <head>
            <title>URL Shortener</title>
            <style>
              body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
              .form-group { margin-bottom: 15px; }
              label { display: block; margin-bottom: 5px; }
              input[type="text"] { width: 100%; padding: 8px; }
              input[type="number"] { width: 100px; padding: 8px; }
              button { padding: 10px 15px; background: #4CAF50; color: white; border: none; cursor: pointer; }
              .result { margin-top: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px; }
            </style>
          </head>
          <body>
            <h1>URL Shortener</h1>
            <form action="/shorten" method="POST">
              <div class="form-group">
                <label for="url">URL to Shorten:</label>
                <input type="text" id="url" name="url" placeholder="https://example.com" required>
              </div>
              
              <div class="form-group">
                <label for="customId">Custom ID (optional):</label>
                <input type="text" id="customId" name="customId" placeholder="my-custom-id">
              </div>
              
              <div class="form-group">
                <label for="expiry">Expires in (days):</label>
                <input type="number" id="expiry" name="expiry" min="1" value="30">
              </div>
              
              <button type="submit">Shorten URL</button>
            </form>
          </body>
        </html>
      `);
    });

    // Shorten URL endpoint
    app.post("/shorten", async (req: Request, res: Response) => {
      try {
        const { url, customId, expiry } = req.body;

        if (!url) {
          return res.status(400).json({ error: "URL is required" });
        }

        const options: any = {};

        if (customId) {
          options.customUrlId = customId;
        }

        if (expiry) {
          options.expiresInDays = parseInt(expiry);
        }

        const result = await shortify.shorten(url, options);

        res.send(`
          <html>
            <head>
              <title>URL Shortened</title>
              <style>
                body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
                .result { margin-top: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px; }
                .copy-btn { padding: 5px 10px; background: #4CAF50; color: white; border: none; cursor: pointer; margin-left: 10px; }
              </style>
            </head>
            <body>
              <h1>URL Shortened</h1>
              
              <div class="result">
                <p><strong>Original URL:</strong> ${result.originalUrl}</p>
                <p>
                  <strong>Shortened URL:</strong> 
                  <a href="${result.shortUrl}" target="_blank">${
          result.shortUrl
        }</a>
                  <button class="copy-btn" onclick="copyToClipboard('${
                    result.shortUrl
                  }')">Copy</button>
                </p>
                <p><strong>URL ID:</strong> ${result.urlId}</p>
                ${
                  result.expiresAt
                    ? `<p><strong>Expires at:</strong> ${new Date(
                        result.expiresAt
                      ).toLocaleString()}</p>`
                    : ""
                }
              </div>
              
              <p><a href="/">← Back to homepage</a></p>
              
              <script>
                function copyToClipboard(text) {
                  navigator.clipboard.writeText(text).then(() => {
                    alert('URL copied to clipboard');
                  });
                }
              </script>
            </body>
          </html>
        `);
      } catch (error) {
        console.error("Error shortening URL:", error);
        res.status(500).json({ error: "Failed to shorten URL" });
      }
    });

    // Redirect shortened URLs
    app.get(
      "/:urlId",
      async (req: Request<{ urlId: string }>, res: Response) => {
        try {
          const { urlId } = req.params;
          const originalUrl = await shortify.resolve(urlId);

          if (originalUrl) {
            return res.redirect(originalUrl);
          } else {
            return res.status(404).send(`
            <html>
              <head>
                <title>URL Not Found</title>
                <style>
                  body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; text-align: center; }
                </style>
              </head>
              <body>
                <h1>URL Not Found</h1>
                <p>The shortened URL you're looking for doesn't exist or has expired.</p>
                <p><a href="/">← Go to homepage</a></p>
              </body>
            </html>
          `);
          }
        } catch (error) {
          console.error("Error resolving URL:", error);
          res.status(500).json({ error: "Failed to resolve URL" });
        }
      }
    );

    // API endpoint to get URL stats
    app.get(
      "/api/stats/:urlId",
      async (req: Request<{ urlId: string }>, res: Response) => {
        try {
          const { urlId } = req.params;
          const stats = await shortify.getStats(urlId);

          if (stats) {
            return res.json(stats);
          } else {
            return res.status(404).json({ error: "URL not found" });
          }
        } catch (error) {
          console.error("Error getting URL stats:", error);
          res.status(500).json({ error: "Failed to get URL stats" });
        }
      }
    );

    // Start the server
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Server running at http://localhost:${PORT}`);
    });
  } catch (error) {
    console.error("Failed to start server:", error);
    process.exit(1);
  }
}

// Graceful shutdown
process.on("SIGINT", async () => {
  console.log("Shutting down server...");
  await shortify.disconnect();
  console.log("Disconnected from MongoDB");
  process.exit(0);
});

// Start the server
startServer();
