"use client"; // components/header/settingsModal/SettingsModal.tsx
import React, { useState, useEffect } from "react";
import ReactModal from "react-modal";
import "bootstrap-icons/font/bootstrap-icons.css";
import { useSelector } from "react-redux";
import handleClearDatabase from "./handlers/handleClearDatabase";
import handleReboot from "./handlers/handleReboot";
import handleSetDateTime from "./handlers/handleSetDateTime";
import handleSubmit from "./handlers/handleSubmit";
import bcrypt from "bcryptjs";
import CryptoJS from "crypto-js";

ReactModal.setAppElement("#__next");

const USERS = {
  Admin: {
    username: "admin",
    // Gehashte Version von "admin" mit bcrypt
    password: "$2a$10$xpq/.tcOJN/LXfzdCcCVrenlBh2nRlM1R1ISY7dd1q2qGWC9Fyd2G",
    role: "Admin",
  },
};

// Funktion zur Generierung eines AES-Schlüssels und IVs
function generateKeyAndIV() {
  const encryptionKey = process.env.NEXT_PUBLIC_ENCRYPTION_KEY;
  const encryptionIV = process.env.NEXT_PUBLIC_ENCRYPTION_IV;

  if (!encryptionKey || !encryptionIV) {
    throw new Error("Encryption key or IV is not defined.");
  }

  const key = CryptoJS.enc.Utf8.parse(encryptionKey);
  const iv = CryptoJS.enc.Utf8.parse(encryptionIV);
  return { key, iv };
}

// Funktion zur Generierung eines Tokens
function generateToken(user) {
  const payload = {
    username: user.username,
    role: user.role,
    exp: Date.now() + 5 * 60 * 1000, // Ablaufzeit: 5 Minuten
  };
  const token = JSON.stringify(payload);
  const { key, iv } = generateKeyAndIV();
  const encryptedToken = CryptoJS.AES.encrypt(token, key, { iv }).toString();
  return encryptedToken;
}

// Funktion zur Entschlüsselung des Tokens
function decryptToken(encryptedToken) {
  const { key, iv } = generateKeyAndIV();
  const bytes = CryptoJS.AES.decrypt(encryptedToken, key, { iv });
  const decryptedToken = bytes.toString(CryptoJS.enc.Utf8);
  return JSON.parse(decryptedToken);
}

function SettingModal({ showModal, onClose }) {
  const [isAdminLoggedIn, setAdminLoggedIn] = useState(false);
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  const [showLoginForm, setShowLoginForm] = useState(false);

  function handleAdminLogin(e) {
    e.preventDefault();
    const user = USERS.Admin;
    bcrypt.compare(password, user.password, (err, isMatch) => {
      if (isMatch) {
        const token = generateToken(user);
        sessionStorage.setItem("token", token);
        localStorage.setItem("isAdminLoggedIn", "true");
        setShowLoginForm(false);
        onClose();
      } else {
        setError(
          "Login fehlgeschlagen. Bitte überprüfen Sie Benutzername und Passwort."
        );
      }
    });
  }

  useEffect(() => {
    if (showModal) {
      const token = sessionStorage.getItem("token");
      if (token) {
        try {
          const { exp } = decryptToken(token);
          if (Date.now() < exp) {
            setAdminLoggedIn(true);
          } else {
            sessionStorage.removeItem("token");
            localStorage.setItem("isAdminLoggedIn", "false");
          }
        } catch (error) {
          console.error("Token-Entschlüsselung fehlgeschlagen:", error);
        }
      }
    }
  }, [showModal]);
  const deviceName_Redux = useSelector((state) => state.variables.deviceName);
  const mac1_Redux = useSelector((state) => state.variables.mac1);
  const ip_Redux = useSelector((state) => state.variables.ip);
  const subnet_Redux = useSelector((state) => state.variables.subnet);
  const gateway_Redux = useSelector((state) => state.variables.gateway);
  const datetime_Redux = useSelector(
    (state) => state.variables.cplInternalTimestamp
  );
  const ntp1_Redux = useSelector((state) => state.variables.ntp1);
  const ntp2_Redux = useSelector((state) => state.variables.ntp2);
  const ntp3_Redux = useSelector((state) => state.variables.ntp3);
  const ntpTimezone_Redux = useSelector((state) => state.variables.ntpTimezone);
  const active_Redux = useSelector((state) => state.variables.ntpActive);

  const [name, setName] = useState(deviceName_Redux || "");
  const [mac1, setMac1] = useState(mac1_Redux || "");
  const [ip, setIp] = useState(ip_Redux || "");
  const [subnet, setSubnet] = useState(subnet_Redux || "");
  const [gateway, setGateway] = useState(gateway_Redux || "");
  const [systemUhr, setSystemUhr] = useState(datetime_Redux || "");
  const [ntp1, setNtp1] = useState(ntp1_Redux || "");
  const [ntp2, setNtp2] = useState(ntp2_Redux || "");
  const [ntp3, setNtp3] = useState(ntp3_Redux || "");
  const [ntpTimezone, setNtpTimezone] = useState(ntpTimezone_Redux || "");
  const [active, setActive] = useState(active_Redux || "");

  const [originalValues, setOriginalValues] = useState({});
  const currentValues = {
    name,
    ip,
    subnet,
    gateway,
    ntp1,
    ntp2,
    ntp3,
    ntpTimezone,
    active,
  };
  const handleAdminLogout = () => {
    sessionStorage.removeItem("token"); // Token aus sessionStorage entfernen
    localStorage.setItem("isAdminLoggedIn", "false"); // Admin-Status im localStorage setzen
  };

  useEffect(() => {
    if (showModal) {
      setName(deviceName_Redux || "");
      setMac1(mac1_Redux || "");
      setIp(ip_Redux || "");
      setSubnet(subnet_Redux || "");
      setGateway(gateway_Redux || "");
      setSystemUhr(datetime_Redux || "");
      setNtp1(ntp1_Redux || "");
      setNtp2(ntp2_Redux || "");
      setNtp3(ntp3_Redux || "");
      setNtpTimezone(ntpTimezone_Redux || "");
      setActive(active_Redux || "");
    }
  }, [showModal]);

  useEffect(() => {
    setOriginalValues({
      name: deviceName_Redux,
      ip: ip_Redux,
      subnet: subnet_Redux,
      gateway: gateway_Redux,
      ntp1: ntp1_Redux,
      ntp2: ntp2_Redux,
      ntp3: ntp3_Redux,
      ntpTimezone: ntpTimezone_Redux,
      active: active_Redux,
    });
  }, [
    deviceName_Redux,
    ip_Redux,
    subnet_Redux,
    gateway_Redux,
    ntp1_Redux,
    ntp2_Redux,
    ntp3_Redux,
    ntpTimezone_Redux,
    active_Redux,
  ]);

  useEffect(() => {
    // Überprüfen, ob ein Token im SessionStorage vorhanden ist
    const token = sessionStorage.getItem("token");
    if (token) {
      try {
        // Token mit CryptoJS entschlüsseln
        const bytes = CryptoJS.AES.decrypt(
          token,
          process.env.NEXT_PUBLIC_ENCRYPTION_KEY
        );
        const decryptedToken = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));

        // Ablaufzeit überprüfen
        if (Date.now() < decryptedToken.exp) {
          setAdminLoggedIn(true);
        } else {
          // Token ist abgelaufen
          sessionStorage.removeItem("token");
          setAdminLoggedIn(false);
        }
      } catch (error) {
        console.error("Fehler beim Entschlüsseln des Tokens:", error);
        setAdminLoggedIn(false);
      }
    }
  }, []);

  return (
    <>
      <ReactModal
        isOpen={showModal}
        onRequestClose={onClose}
        shouldCloseOnOverlayClick={false}
        style={{
          overlay: { backgroundColor: "rgba(0, 0, 0, 0.5)", zIndex: 100 },
          content: {
            top: "50%",
            left: "50%",
            right: "auto",
            bottom: "auto",
            marginRight: "-50%",
            transform: "translate(-50%, -50%)",
            width: "80%",
            maxWidth: "800px",
            padding: "20px",
            borderRadius: "8px",
            border: "none",
            position: "relative",
          },
        }}
      >
        <button
          onClick={onClose}
          style={{
            position: "absolute",
            top: "10px",
            right: "10px",
            background: "transparent",
            border: "none",
            cursor: "pointer",
            fontSize: "24px",
          }}
        >
          <i className="bi bi-x-circle-fill"></i>
        </button>

        {/* Hauptinhalt oder Login-Formular */}
        {showLoginForm ? (
          <div className="text-black">
            <h2 className="text-lg font-bold mb-4">Admin Login</h2>
            <form onSubmit={(e) => e.preventDefault()}>
              <div className="mb-4">
                <label className="block text-sm font-medium">
                  Benutzername:
                </label>
                <input
                  type="text"
                  className="border border-gray-300 rounded p-2 w-full"
                  value={username}
                  onChange={(e) => setUsername(e.target.value)}
                />
              </div>
              <div className="mb-4">
                <label className="block text-sm font-medium">Passwort:</label>
                <input
                  type="password"
                  className="border border-gray-300 rounded p-2 w-full"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                />
              </div>
              {error && <p className="text-red-500">{error}</p>}
              <button
                onClick={handleAdminLogin}
                className="bg-littwin-blue text-white px-4 py-2 rounded w-full"
              >
                Anmelden
              </button>
            </form>
          </div>
        ) : (
          <div className="text-black">
            <h2 className="text-lg font-bold mb-4">System:</h2>
            <form>
              <div className="mb-4">
                <label className="block text-sm font-medium">Name:</label>
                <input
                  type="text"
                  className="border border-gray-300 rounded p-2 w-full"
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                />
              </div>

              <div className="mb-4 grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium">
                    MAC Adresse 1:
                  </label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={mac1}
                    onChange={(e) => setMac1(e.target.value)}
                    disabled
                  />
                </div>
              </div>

              <div className="mb-4 grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium">IP:</label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={ip}
                    onChange={(e) => setIp(e.target.value)}
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium">Subnet:</label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={subnet}
                    onChange={(e) => setSubnet(e.target.value)}
                  />
                </div>
              </div>

              <div className="mb-4 grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium">Gateway:</label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={gateway}
                    onChange={(e) => setGateway(e.target.value)}
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium">
                    Systemuhr:
                  </label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={systemUhr}
                    disabled
                  />
                  {/* Button für Systemzeit übernehmen */}

                  <div className="flex w-full mt-1 justify-end">
                    <button
                      className="bg-littwin-blue text-white px-4 py-2 rounded"
                      onClick={() => {
                        if (
                          window.confirm(
                            "Möchten Sie wirklich die Systemzeit übernehmen?"
                          )
                        ) {
                          handleSetDateTime();
                        }
                      }}
                    >
                      Systemzeit übernehmen
                    </button>
                  </div>
                </div>
              </div>

              {/* SNTP Client */}
              <h3 className="text-sm font-bold mb-2">SNTP Client:</h3>
              <div className="mb-4 grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium">
                    IP NTP Server 1:
                  </label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={ntp1}
                    onChange={(e) => setNtp1(e.target.value)}
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium">
                    IP NTP Server 2:
                  </label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={ntp2}
                    onChange={(e) => setNtp2(e.target.value)}
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium">
                    IP NTP Server 3:
                  </label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={ntp3}
                    onChange={(e) => setNtp3(e.target.value)}
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium">Zeitzone:</label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={ntpTimezone}
                    onChange={(e) => setNtpTimezone(e.target.value)}
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium">
                    NTP Active:
                  </label>
                  <input
                    type="text"
                    className="border border-gray-300 rounded p-2 w-full"
                    value={active}
                    onChange={(e) => setActive(e.target.value)}
                  />
                </div>
              </div>

              {/* Modal Footer */}
              <div className="flex justify-between mt-4">
                <button
                  className="bg-littwin-blue text-white px-4 py-2 rounded"
                  onClick={() => handleReboot()}
                >
                  Neustart CPL
                </button>
                <button
                  onClick={() => {
                    isAdminLoggedIn
                      ? handleAdminLogout()
                      : setShowLoginForm(true);
                  }}
                  className="bg-littwin-blue text-white px-4 py-2 rounded"
                >
                  {isAdminLoggedIn ? "Admin abmelden" : "Admin anmelden"}
                </button>
                <button
                  className="bg-littwin-blue text-white px-4 py-2 rounded"
                  onClick={() => handleClearDatabase()}
                >
                  Datenbank leeren
                </button>
                <button
                  onClick={() => handleSubmit(originalValues, currentValues)}
                  className="bg-littwin-blue text-white px-4 py-2 rounded"
                >
                  Übernehmen
                </button>
              </div>
            </form>
          </div>
        )}
      </ReactModal>
    </>
  );
}

export default SettingModal;
