const express = require("express");
const { user } = require("../models");
const {
  validateInput,
  handleValidationErrorForAPI,
} = require("../services/ValidationService");
const Web3Service = require("../services/Web3Service");

const router = express.Router();

router.get("/", async (req, res, next) => {
  try {
    const users = await user.findAll();
    res.json({ success: true, data: users });
  } catch (err) {
    next(err);
  }
});

const createUserRules = {
  name: "required|string",
};

router.post(
  "/",
  validateInput(createUserRules),
  handleValidationErrorForAPI,
  async (req, res, next) => {
    try {
      await user.create(req.body);
      res.json({ success: true, message: "User created successfully" });
    } catch (err) {
      next(err);
    }
  }
);

// POST /api/v1/user/wallet
router.post(
  "/wallet",
  validateInput({ id: "required|integer" }),
  handleValidationErrorForAPI,
  async (req, res) => {
    try {
      const { id: userId } = req.body;
      const u = await user.findByPk(userId);

      if (!u) {
        return res
          .status(404)
          .json({ success: false, error: "User not found" });
      }

      const wallet = Web3Service.createWallet();
      await u.update({ wallet_id: wallet.address });
      res.json({
        success: true,
        data: { address: wallet.address, privateKey: wallet.privateKey },
      });
    } catch (err) {
      res.status(500).json({ success: false, error: err.message });
    }
  }
);

// GET /api/v1/user/sign?private_key=...&message=...
router.get("/sign", (req, res) => {
  try {
    const { private_key, message } = req.query;
    const signed = Web3Service.signMessage(
      private_key,
      message || "default message"
    );
    res.json({ success: true, data: signed });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

// GET /api/v1/user/account?private_key=...
router.get("/account", async (req, res) => {
  try {
    const { private_key } = req.query;
    const account =
      Web3Service.web3.eth.accounts.privateKeyToAccount(private_key);
    const balance = await Web3Service.getBalance(account.address);
    res.json({ success: true, data: { address: account.address, balance } });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

// GET /api/v1/user/transfer?private_key=...&to_address=...&amount=...
router.get("/transfer", async (req, res) => {
  try {
    const { private_key, to_address, amount } = req.query;
    const tx = await Web3Service.transfer(private_key, to_address, amount);
    res.json({ success: true, data: tx });
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

router.get("/:id", async (req, res, next) => {
  try {
    const u = await user.findByPk(req.params.id);
    if (!u) {
      return res.status(404).json({ error: "User not found" });
    }
    res.json({ success: true, data: u });
  } catch (err) {
    next(err);
  }
});

const updateUserRules = {
  name: "string",
  wallet_id: "string",
};

router.put(
  "/:id",
  validateInput(updateUserRules),
  handleValidationErrorForAPI,
  async (req, res, next) => {
    try {
      const u = await user.findByPk(req.params.id);
      if (!u) {
        return res.status(404).json({ error: "User not found" });
      }
      await u.update(req.body);
      res.json({ success: true, message: "User updated successfully" });
    } catch (err) {
      next(err);
    }
  }
);

router.delete("/:id", async (req, res, next) => {
  try {
    const u = await user.findByPk(req.params.id);
    if (!u) {
      return res.status(404).json({ error: "User not found" });
    }
    await u.destroy();
    res.json({ success: true, message: "User deleted successfully" });
  } catch (err) {
    next(err);
  }
});

module.exports = router;
