import express from 'express';
import axios from 'axios';
import { Database } from '../database/database.js';
import { predictCreationDate } from '../lib/create-date.js';
import { authenticateApiKey, apiLimiter } from '../middleware/midware.js';
import { Job } from '../models.js';
const AntibanRoutes = express.Router();
import * as uuid from 'uuid';

const protectedUsers = [6477856957, 1191668125, 1448273246, 1054295664, 6444305696]; 

const TelegramUser = async (user_id) => {
  const options = {
    method: 'GET',
    url: 'https://randydev-meta-ai.hf.space/user/get_user',
    params: {
      user_id: user_id
    }
  };
  try {
    const response = await axios.request(options);
    return response.data;
  } catch (error) {
    console.error(error);
    return null;
  }
}

const TelegramUserStatusBan = async (user_id) => {
  const options = {
    method: 'GET',
    url: 'https://randydev-meta-ai.hf.space/user/status/ban',
    params: {
      username: user_id
    }
  };
  try {
    const response = await axios.request(options);
    return response.data;
  } catch (error) {
    console.error(error);
    return null;
  }
}

const TelegramUserStoryDL = async (link) => {
  const options = {
    method: 'GET',
    url: 'https://randydev-meta-ai.hf.space/user/get_story',
    params: {
      link: link
    }
  };
  try {
    const response = await axios.request(options);
    return response.data;
  } catch (error) {
    console.error(error);
    return null;
  }
}

const GetChatRaw = async (username) => {
  const options = {
    method: 'GET',
    url: 'https://randydev-meta-ai.hf.space/user/raw/getchat',
    params: {
      username: username
    }
  };
  try {
    const response = await axios.request(options);
    return response.data;
  } catch (error) {
    console.error(error);
    return null;
  }
}

const GetAuthorChat = async (username) => {
  const options = {
    method: 'GET',
    url: 'https://randydev-meta-ai.hf.space/user/author/admin',
    params: {
      username: username
    }
  };
  try {
    const response = await axios.request(options);
    return response.data;
  } catch (error) {
    console.error(error);
    return null;
  }
}

/**
 * @swagger
 * /api/v1/user/status/ban:
 *   get:
 *     summary: Telegram User Status Ban
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: username
 *         required: true
 *         description: null
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/status/ban", authenticateApiKey, apiLimiter, async (req, res) => {
    const Username = req.query.username;
    if (!Username) {
        return res.status(400).json({ error: "Invalid or missing username" });
    }
    try {
        const result = await TelegramUserStatusBan(Username);
        res.json(result);
    } catch (error) {
        res.status(500).json({ error: "Failed to fetch user info" });
    }
});

/**
 * @swagger
 * /api/v1/user/author/admin:
 *   get:
 *     summary: Telegram Author Admin
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: username
 *         required: true
 *         description: null
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/author/admin", authenticateApiKey, apiLimiter, async (req, res) => {
    const Username = req.query.username;
    if (!Username) {
        return res.status(400).json({ error: "Invalid or missing username" });
    }
    try {
        const result = await GetAuthorChat(Username);
        res.json(result);
    } catch (error) {
        res.status(500).json({ error: "Failed to fetch user info" });
    }
});


/**
 * @swagger
 * /api/v1/user/raw/getchat:
 *   get:
 *     summary: Telegram Get Chat
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: username
 *         required: true
 *         description: null
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/raw/getchat", authenticateApiKey, apiLimiter, async (req, res) => {
    const Username = req.query.username;
    if (!Username) {
        return res.status(400).json({ error: "Invalid or missing username" });
    }
    try {
        const result = await GetChatRaw(Username);
        res.json(result);
    } catch (error) {
        res.status(500).json({ error: "Failed to fetch user info" });
    }
});

/**
 * @swagger
 * /api/v1/user/story/task:
 *   get:
 *     summary: Telegram User Story Downloader
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: story_url
 *         required: true
 *         description: Telegram Story URL to download
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Download started successfully
 */
AntibanRoutes.get("/api/v1/user/story/task", authenticateApiKey, apiLimiter, async (req, res) => {
    const Links = req.query.story_url;
    if (!Links) {
        return res.status(400).json({ error: "Invalid or missing story_url" });
    }

    const job_id = uuid.v4();
    const newJob = new Job({ job_id, status: "pending" });
    await newJob.save();
    setTimeout(async () => {
        try {
            const result = await TelegramUserStoryDL(Links);
            const story_bytes = result.download;

            await Job.findOneAndUpdate(
                { job_id },
                { status: "completed", story_bytes }
            );
        } catch (err) {
            await Job.findOneAndUpdate({ job_id }, { status: "failed" });
        }
    }, 10000);

    res.json({ message: "Download started", status: "processing", job_id });
});

/**
 * @swagger
 * /api/v1/user/story/task/{job_id}:
 *   delete:
 *     summary: Check Telegram User Story Delete Job ID
 *     tags: [User]
 *     parameters:
 *       - in: path
 *         name: job_id
 *         required: true
 *         description: Job ID to delete 
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Returns job Has been deleted
 */
AntibanRoutes.delete("/api/v1/user/story/task/:job_id", authenticateApiKey, apiLimiter, async (req, res) => {
    const { job_id } = req.params;
    
    const deletedJob = await Job.findOneAndDelete({ job_id });

    if (!deletedJob) {
        return res.status(404).json({ error: "Job not found" });
    }
    res.json({ message: "Job deleted successfully", job_id });
});


/**
 * @swagger
 * /api/v1/user/story/task/{job_id}:
 *   get:
 *     summary: Check Telegram User Story Download Status
 *     tags: [User]
 *     parameters:
 *       - in: path
 *         name: job_id
 *         required: true
 *         description: Job ID to check download status
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Returns job status and story bytes if completed
 */
AntibanRoutes.get("/api/v1/user/story/task/:job_id", authenticateApiKey, apiLimiter, async (req, res) => {
    const job = await Job.findOne({ job_id: req.params.job_id });

    if (!job) return res.status(404).json({ error: "Job not found" });

    res.json({
        job_id: job.job_id,
        status: job.status,
        story_bytes: job.status === "completed" ? job.story_bytes : null
    });
});

/**
 * @swagger
 * /api/v1/user/info:
 *   get:
 *     summary: Telegram User Info
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: user_id
 *         required: true
 *         description: null
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/info", authenticateApiKey, apiLimiter, async (req, res) => {
    const userId = req.query.user_id;
    if (!userId) {
        return res.status(400).json({ error: "Invalid or missing user_id" });
    }

    try {
        const result = await TelegramUser(userId);
        res.json(result);
    } catch (error) {
        res.status(500).json({ error: "Failed to fetch user info" });
    }
});


/**
 * @swagger
 * /api/v1/user/creation-date:
 *   get:
 *     summary: Telegram creation date User
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: user_id
 *         required: true
 *         description: null
 *         schema:
 *           type: number
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/creation-date", authenticateApiKey, apiLimiter, (req, res) => {
    const userId = Number(req.query.user_id);
    if (!userId || isNaN(userId)) {
        return res.status(400).json({ error: "Invalid or missing user_id" });
    }

    const result = predictCreationDate(userId);
    res.json({ user_id: userId, estimated_creation: result });
});

AntibanRoutes.get("/api/v1/user/api-key-info", authenticateApiKey, apiLimiter, async (req, res) => {
    const dbClient = new Database("AkenoXJs");
    const collectionKey = dbClient.collection("api_keys");
    const apiKey = req.headers["x-api-key"];
    try {
        if (!apiKey) {
            return res.status(400).json({ error: "Missing API key" });
        }
        const existingUserKey = await collectionKey.findOne({ key: apiKey });
        if (!existingUserKey) {
            return res.status(401).json({ message: "API key not found" });
        }
        res.json({ 
          owner_id: existingUserKey.owner,
          key: existingUserKey.key,
          ip_addresses: existingUserKey.ip_addresses || []
        });
    } catch (error) {
        res.status(500).json({ error: "Failed to fetch user info" });
    }
});

/**
 * @swagger
 * /api/v1/user/ban-user:
 *   post:
 *     summary: Telegram Ban User
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: user_id
 *         required: true
 *         description: null
 *         schema:
 *           type: number
 *       - in: query
 *         name: reason
 *         required: false
 *         description: null
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.post("/api/v1/user/ban-user", authenticateApiKey, apiLimiter, async (req, res) => {
    const dbClient = new Database("AkenoXJs");
    const collection = dbClient.collection("ban_users");
    const collectionKey = dbClient.collection("api_keys");
    try {
        const apiKey = req.headers["x-api-key"];
        const userIdString = req.query.user_id;
        const reasonString = req.query.reason;
        const userIdNumber = Number(userIdString);

        if (!apiKey) {
            return res.status(400).json({ error: "Missing API key in headers" });
        }
        if (isNaN(userIdNumber)) {
            return res.status(400).json({ error: "Invalid or missing user_id" });
        }

        const existingUserKey = await collectionKey.findOne({ key: apiKey });
        if (!existingUserKey) {
            return res.status(401).json({ message: "API key not found" });
        }

       /*
        if (existingUserKey.owner === userIdNumber) {
            return res.status(200).json({ 
              message: `User ${userIdNumber} cannot be banned because they created the API key`,
              is_ban: false
            });
        }
        */
    
        const result = await collectionKey.find({}).toArray();
        let userIds = [];
        for (const data of result) {
          if (data.owner !== undefined) {
            userIds.push(data.owner);
          }
        }

        /*
        if (userIds.includes(userIdNumber)) {
            return res.status(403).json({ 
              message: `User ${userIdNumber} cannot be banned because they created the API key`,
              is_ban: false 
            });
        }
        */

        if (protectedUsers.includes(userIdNumber)) {
            return res.status(403).json({ 
              message: `User ${userIdNumber} is a protected admin and cannot be banned`,
              is_ban: false 
            });
        }

        const existingBan = await collection.findOne({ user_ban: userIdNumber });
        if (existingBan) {
            return res.status(200).json({ message: `User ${userIdNumber} is already banned`, is_ban: true });
        }

        await collection.updateOne(
            { key: existingUserKey.key },
            { $addToSet: { user_ban: userIdNumber }, $set: { updatedAt: new Date(), owner: existingUserKey.owner } },
            { upsert: true }
        );

        res.json({ message: `User ${userIdNumber} successfully banned`, is_ban: true });

    } catch (error) {
        res.status(500).json({ error: `Internal server error: ${error.message}` });
    }
});

/**
 * @swagger
 * /api/v1/user/anti-broadcast:
 *   post:
 *     summary: Telegram Anti broadcast
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: user_id
 *         required: true
 *         description: null
 *         schema:
 *           type: number
 *       - in: query
 *         name: text
 *         required: true
 *         description: null
 *         schema:
 *           type: string
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.post("/api/v1/user/anti-broadcast", authenticateApiKey, async (req, res) => {
    const dbClient = new Database("AkenoXJs");
    const collection = dbClient.collection("users_broadcast");
    const collectionKey = dbClient.collection("api_keys");

    try {
        const apiKey = req.headers["x-api-key"];
        const userIdString = req.query.user_id;
        const WorldString = req.query.text;
        const userIdNumber = Number(userIdString);

        if (!apiKey) {
            return res.status(400).json({ error: "Missing API key in headers" });
        }
        if (!WorldString) {
            return res.status(400).json({ error: "Missing params: text" });
        }
        if (isNaN(userIdNumber)) {
            return res.status(400).json({ error: "Invalid or missing user_id" });
        }
        
        const existingUserKey = await collectionKey.findOne({ key: apiKey });

        if (!existingUserKey) {
            return res.status(401).json({ message: "API key not found" });
        }

        if (existingUserKey.owner === userIdNumber) {
            return res.status(200).json({ 
                message: `User ${userIdNumber} cannot be broadcast because they created the API key`,
                is_broadcast: false
            });
        }

        if (protectedUsers.includes(userIdNumber)) {
            return res.status(403).json({ 
              message: `User ${userIdNumber} is a protected admin and cannot be banned`,
              is_ban: false 
            });
        }

        const existingBroadcast = await collection.findOne({ user_id: userIdNumber });
        if (existingBroadcast) {
            return res.status(200).json({ message: `User ${userIdNumber} is already broadcasting`, is_broadcast: true });
        }

        if (WorldString.length > 3096) {
            return res.status(400).json({ message: `User ${userIdNumber} is sending a spam broadcast`, is_broadcast: true });
        }

        await collection.updateOne(
            { user_id: userIdNumber },
            { 
                $set: { 
                    text: WorldString, 
                    updatedAt: new Date(), 
                    owner: existingUserKey.owner, 
                    is_broadcast: true 
                } 
            },
            { upsert: true }
        );

        res.json({ message: `User ${userIdNumber} successfully broadcast`, is_broadcast: true });

    } catch (error) {
        res.status(500).json({ error: `Internal server error: ${error.message}` });
    }
});

/**
 * @swagger
 * /api/v1/user/check-broadcast:
 *   get:
 *     summary: Telegram Check Anti broadcast
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: user_id
 *         required: true
 *         description: null
 *         schema:
 *           type: number
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/check-broadcast", authenticateApiKey, async (req, res) => {
    const dbClient = new Database("AkenoXJs");
    const collection = dbClient.collection("users_broadcast");

    try {
        const userIdString = req.query.user_id;
        const userIdNumber = Number(userIdString);

        if (isNaN(userIdNumber)) {
            return res.status(400).json({ error: "Invalid or missing user_id" });
        }

        const GikesUser = await collection.findOne({ user_id: userIdNumber });

        if (GikesUser) {
            return res.status(200).json({ message: `User ${userIdNumber} is broadcast`, is_broadcast: true });
        } else {
            return res.status(200).json({ message: `User ${userIdNumber} is not broadcast`, is_broadcast: false });
        }

    } catch (error) {
        res.status(500).json({ error: `Internal server error: ${error.message}` });
    }
});

/**
 * @swagger
 * /api/v1/user/check-ban:
 *   get:
 *     summary: Telegram Check Banned
 *     tags: [User]
 *     parameters:
 *       - in: query
 *         name: user_id
 *         required: true
 *         description: null
 *         schema:
 *           type: number
 *       - in: header
 *         name: x-api-key
 *         required: true
 *         description: API key for authentication
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Success
 */
AntibanRoutes.get("/api/v1/user/check-ban", authenticateApiKey, async (req, res) => {
    const dbClient = new Database("AkenoXJs");
    const collection = dbClient.collection("ban_users");

    try {
        const userIdString = req.query.user_id;
        const userIdNumber = Number(userIdString);

        if (isNaN(userIdNumber)) {
            return res.status(400).json({ error: "Invalid or missing user_id" });
        }

        const bannedUser = await collection.findOne({ user_ban: userIdNumber });

        if (bannedUser) {
            return res.status(200).json({ message: `User ${userIdNumber} is banned`, is_ban: true });
        } else {
            return res.status(200).json({ message: `User ${userIdNumber} is not banned`, is_ban: false });
        }

    } catch (error) {
        res.status(500).json({ error: `Internal server error: ${error.message}` });
    }
});

export { AntibanRoutes };