import { useEffect, useReducer, useCallback } from "react";
import { appReducer, initialAppState } from "./reducer";
import { api } from "./api";
import { CleanConfig, ActiveTab } from "./types";
import { TabHeaders } from "./components/TabHeaders";
import { GeneralTab } from "./components/GeneralTab";
import { RulesTab } from "./components/RulesTab";
import { LicenseTab } from "./components/LicenseTab";
import "./App.css";
import appStyles from "./App.module.css";

function App() {
  const [state, dispatch] = useReducer(appReducer, initialAppState);

  useEffect(() => {
    const init = async () => {
      try {
        const payload = await api.getInitialState();

        dispatch({
          type: "INITIALIZE",
          payload: {
            config: payload.config,
            hotkeyConflict: payload.hotkey_conflict,
            hwid: payload.hwid,
            isLicensed: payload.is_licensed,
          },
        });
      } catch (err) {
        console.error("Failed to initialize settings:", err);
      } finally {
        try {
          await api.showSettingsWindow();
        } catch (e) {
          console.error("Failed to show window:", e);
        }
      }
    };

    init();
  }, []);

  const updateConfig = useCallback(
    async (newConfigParams: Partial<CleanConfig>) => {
      const updatedConfig = { ...state.config, ...newConfigParams };
      dispatch({ type: "SET_CONFIG", payload: newConfigParams });

      try {
        await api.updateConfig(updatedConfig);

        const status = await api.getHotkeyStatus();

        dispatch({ type: "SET_HOTKEY_CONFLICT", payload: status[1] });
      } catch (err) {
        console.error("Failed to update config:", err);
      }
    },
    [state.config],
  );

  const handleActivate = async () => {
    if (state.tabState.tab !== "license") {
      return;
    }

    const licenseKey = state.tabState.keyInput.trim();

    if (!licenseKey) {
      dispatch({
        type: "ACTIVATION_FAILURE",
        payload: "Please enter a license key.",
      });
      return;
    }

    dispatch({ type: "START_ACTIVATION" });

    try {
      await api.activateLicense(licenseKey);

      dispatch({ type: "ACTIVATION_SUCCESS" });
    } catch (err: unknown) {
      dispatch({ type: "ACTIVATION_FAILURE", payload: String(err) });
    }
  };

  const handleOfflineActivate = async (token: string) => {
    if (state.tabState.tab !== "license") {
      return;
    }

    dispatch({ type: "START_ACTIVATION" });

    try {
      await api.verifyOfflineToken(token);

      dispatch({ type: "ACTIVATION_SUCCESS" });
    } catch (err: unknown) {
      dispatch({ type: "ACTIVATION_FAILURE", payload: String(err) });
    }
  };

  const isRecording =
    state.tabState.tab === "general" && state.tabState.isRecording;

  useEffect(() => {
    if (!isRecording) {
      return;
    }

    const handleKeyDown = (e: KeyboardEvent) => {
      e.preventDefault();
      e.stopPropagation();

      if (["Control", "Alt", "Shift", "Meta"].includes(e.key)) {
        return;
      }

      if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) {
        return;
      }

      const parts: string[] = [];

      if (e.ctrlKey) {
        parts.push("Ctrl");
      }

      if (e.altKey) {
        parts.push("Alt");
      }

      if (e.shiftKey) {
        parts.push("Shift");
      }

      if (e.metaKey) {
        parts.push("Super");
      }

      let keyName = e.key;

      if (keyName === " ") {
        keyName = "Space";
      }

      if (keyName.length === 1) {
        keyName = keyName.toUpperCase();
      }

      parts.push(keyName);

      const hotkeyStr = parts.join("+");

      updateConfig({ hotkey: hotkeyStr });
      dispatch({ type: "SET_RECORDING", payload: false });
    };

    window.addEventListener("keydown", handleKeyDown);

    return () => {
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [isRecording, updateConfig]);

  const activeTab: ActiveTab = state.tabState.tab;

  return (
    <div className="app-container">
      <div className={appStyles["header"]}>
        <div className={appStyles["logo-section"]}>
          <div className={appStyles["logo-icon"]}>C</div>
          <div className={appStyles["logo-title"]}>CleanCopy</div>
        </div>
      </div>

      <TabHeaders
        activeTab={activeTab}
        isLicensed={state.isLicensed}
        onTabChange={(tab) => dispatch({ type: "SET_TAB", payload: tab })}
      />

      {state.tabState.tab === "general" && (
        <GeneralTab
          config={state.config}
          isConflict={state.hotkeyConflict}
          isRecording={isRecording}
          onToggleRecording={() =>
            dispatch({ type: "SET_RECORDING", payload: !isRecording })
          }
          onUpdateConfig={updateConfig}
        />
      )}

      {state.tabState.tab === "rules" && (
        <RulesTab config={state.config} onUpdateConfig={updateConfig} />
      )}

      {state.tabState.tab === "license" && (
        <LicenseTab
          isLicensed={state.isLicensed}
          hwid={state.hwid}
          keyInput={state.tabState.keyInput}
          isActivating={state.tabState.isActivating}
          error={state.tabState.error}
          onKeyInputChange={(val) =>
            dispatch({ type: "SET_LICENSE_KEY_INPUT", payload: val })
          }
          onActivate={handleActivate}
          onOfflineActivate={handleOfflineActivate}
        />
      )}
    </div>
  );
}

export default App;
