import User, { Gender } from "./models/user.js";
import Client from "./models/client.js";
import Logging from "@hibas123/nodelogging";
import RegCode from "./models/regcodes.js";
import moment from "moment";
import Permission from "./models/permissions.js";
import { ObjectId } from "mongodb";
import DB from "./database.js";
import TwoFactor from "./models/twofactor.js";

import LoginToken from "./models/login_token.js";
import Mail from "./models/mail.js";

export default async function TestData() {
   Logging.warn("Running in dev mode! Database will be cleared!");
   // await DB.db.dropDatabase();

   let mail = await Mail.findOne({ mail: "test@test.de" });
   if (!mail) {
      mail = Mail.new({
         mail: "test@test.de",
         primary: true,
         verified: true,
      });

      await Mail.save(mail);
   }

   let u = await User.findOne({ username: "test" });
   if (!u) {
      Logging.log("Adding test user");
      u = User.new({
         username: "test",
         birthday: new Date(),
         gender: Gender.male,
         name: "Test Test",
         password:
            "125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc",
         salt: "test",
         admin: true,
         phones: [
            { phone: "+4915962855955", primary: true, verified: true },
            { phone: "+4915962855932", primary: false, verified: false },
         ],
         mails: [mail._id],
      });
      await User.save(u);
   }

   let c = await Client.findOne({ client_id: "test001" });
   if (!c) {
      Logging.log("Adding test client");
      c = Client.new({
         client_id: "test001",
         client_secret: "test001",
         internal: true,
         maintainer: u._id,
         name: "Test Client",
         website: "http://example.com",
         redirect_url: "http://example.com",
         featured: true,
         description:
            "This client is just for testing purposes. It does not have any functionality.",
      });
      await Client.save(c);
   }

   let perm = await Permission.findById("507f1f77bcf86cd799439011");
   if (!perm) {
      Logging.log("Adding test permission");
      perm = Permission.new({
         _id: new ObjectId("507f1f77bcf86cd799439011"),
         name: "TestPerm",
         description: "Permission just for testing purposes",
         client: c._id,
      });

      await (await (Permission as any)._collection).insertOne(perm);

      // Permission.save(perm);
   }

   let r = await RegCode.findOne({ token: "test" });
   if (!r) {
      Logging.log("Adding test reg_code");
      r = RegCode.new({
         token: "test",
         valid: true,
         validTill: moment().add("1", "year").toDate(),
      });
      await RegCode.save(r);
   }

   let t = await TwoFactor.findOne({ user: u._id, type: 0 });
   if (!t) {
      Logging.log("Adding test TOTP")
      t = TwoFactor.new({
         user: u._id,
         name: "Test OTP",
         type: 0,
         valid: true,
         data: "IIRW2P2UJRDDO2LDIRYW4LSREZLWMOKDNBJES2LLHRREK3R6KZJQ",
         expires: null,
      });
      await TwoFactor.save(t);
   }

   // let tw = await TwoFactor.findOne({ user: u._id, type: 2 });
   // if (!tw) {
   //    Logging.log("Adding test WebAuthn")
   //    tw = TwoFactor.new({
   //       user: u._id,
   //       name: "WebAuthn",
   //       type: 2,
   //       valid: true,
   //       data: {
   //          device: {
   //             credentialPublicKey: Buffer.from("pQECAyYgASFYINiHCRopJIn1GoTXq7SpDTJR1nzocqOWhjvpYaKLzzhSIlggvuHhjABe8NxbOIGA11vrd5deUT5R30anpE7W7xzPcsk=", "base64"),
   //             credentialID: Buffer.from("i/BJiffx0bxjQ9Ptyvc9ORELXALxrvD6pad1Xc/2nDI=", "base64"),
   //             counter: 1,
   //             transports: [
   //                "usb"
   //             ]
   //          }
   //       }
   //    });
   //    await TwoFactor.save(tw);
   // }

   let login_token = await LoginToken.findOne({ token: "test01" });
   if (login_token) await LoginToken.delete(login_token);

   login_token = LoginToken.new({
      browser: "DEMO",
      ip: "10.0.0.1",
      special: false,
      token: "test01",
      valid: true,
      validTill: moment().add("10", "years").toDate(),
      user: u._id,
      validated: true,
   });
   await LoginToken.save(login_token);

   let special_token = await LoginToken.findOne({ token: "test02" });
   if (special_token) await LoginToken.delete(special_token);

   special_token = LoginToken.new({
      browser: "DEMO",
      ip: "10.0.0.1",
      special: true,
      token: "test02",
      valid: true,
      validTill: moment().add("10", "years").toDate(),
      user: u._id,
      validated: true,
   });
   await LoginToken.save(special_token);

   // setInterval(() => {
   //    let code = speakeasy.totp({
   //       secret: t.data,
   //       encoding: "base32"
   //    })
   //    Logging.debug("OTC Code is:", code);
   // }, 1000)

   Logging.log("Finished adding test data");
}

