import { useCallback, useEffect, useState } from "react";

import { useSettingsStore } from "@hooks/stores";
import { JsonRpcResponse, useJsonRpc } from "@hooks/useJsonRpc";
import { useDeviceUiNavigation } from "@hooks/useAppNavigation";
import { Button } from "@components/Button";
import Checkbox from "@components/Checkbox";
import { ConfirmDialog } from "@components/ConfirmDialog";
import { GridCard } from "@components/Card";
import { SettingsItem } from "@components/SettingsItem";
import { SettingsPageHeader } from "@components/SettingsPageheader";
import { NestedSettingsGroup } from "@components/NestedSettingsGroup";
import { TextAreaWithLabel } from "@components/TextArea";
import { InputFieldWithLabel } from "@components/InputField";
import { SelectMenuBasic } from "@components/SelectMenuBasic";
import { isOnDevice } from "@/main";
import notifications from "@/notifications";
import { m } from "@localizations/messages.js";
import { sleep } from "@/utils";

export default function SettingsAdvancedRoute() {
  const { send } = useJsonRpc();
  const { navigateTo } = useDeviceUiNavigation();

  const [sshKey, setSSHKey] = useState<string>("");
  const { setDeveloperMode } = useSettingsStore();
  const [devChannel, setDevChannel] = useState(false);
  const [usbEmulationEnabled, setUsbEmulationEnabled] = useState(false);
  const [showLoopbackWarning, setShowLoopbackWarning] = useState(false);
  const [localLoopbackOnly, setLocalLoopbackOnly] = useState(false);
  const [updateTarget, setUpdateTarget] = useState<string>("app");
  const [appVersion, setAppVersion] = useState<string>("");
  const [systemVersion, setSystemVersion] = useState<string>("");

  const settings = useSettingsStore();

  useEffect(() => {
    send("getDevModeState", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) return;
      const result = resp.result as { enabled: boolean };
      setDeveloperMode(result.enabled);
    });

    send("getSSHKeyState", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) return;
      setSSHKey(resp.result as string);
    });

    send("getUsbEmulationState", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) return;
      setUsbEmulationEnabled(resp.result as boolean);
    });

    send("getDevChannelState", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) return;
      setDevChannel(resp.result as boolean);
    });

    send("getLocalLoopbackOnly", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) return;
      setLocalLoopbackOnly(resp.result as boolean);
    });
  }, [send, setDeveloperMode]);

  const getUsbEmulationState = useCallback(() => {
    send("getUsbEmulationState", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) return;
      setUsbEmulationEnabled(resp.result as boolean);
    });
  }, [send]);

  const handleUsbEmulationToggle = useCallback(
    (enabled: boolean) => {
      send("setUsbEmulationState", { enabled: enabled }, (resp: JsonRpcResponse) => {
        if ("error" in resp) {
          notifications.error(
            enabled
              ? m.advanced_error_usb_emulation_enable({ error: resp.error.data || m.unknown_error() })
              : m.advanced_error_usb_emulation_disable({ error: resp.error.data || m.unknown_error() })
          );
          return;
        }
        setUsbEmulationEnabled(enabled);
        getUsbEmulationState();
      });
    },
    [getUsbEmulationState, send],
  );

  const handleResetConfig = useCallback(() => {
    send("resetConfig", {}, (resp: JsonRpcResponse) => {
      if ("error" in resp) {
        notifications.error(
          m.advanced_error_reset_config({ error: resp.error.data || m.unknown_error() })
        );
        return;
      }
      notifications.success(m.advanced_success_reset_config());
    });
  }, [send]);

  const handleUpdateSSHKey = useCallback(() => {
    send("setSSHKeyState", { sshKey }, (resp: JsonRpcResponse) => {
      if ("error" in resp) {
        notifications.error(
          m.advanced_error_update_ssh_key({ error: resp.error.data || m.unknown_error() })
        );
        return;
      }
      notifications.success(m.advanced_success_update_ssh_key());
    });
  }, [send, sshKey]);

  const handleDevModeChange = useCallback(
    (developerMode: boolean) => {
      send("setDevModeState", { enabled: developerMode }, (resp: JsonRpcResponse) => {
        if ("error" in resp) {
          notifications.error(
            m.advanced_error_set_dev_mode({ error: resp.error.data || m.unknown_error() })
          );
          return;
        }
        setDeveloperMode(developerMode);
      });
    },
    [send, setDeveloperMode],
  );

  const handleDevChannelChange = useCallback(
    (enabled: boolean) => {
      send("setDevChannelState", { enabled }, (resp: JsonRpcResponse) => {
        if ("error" in resp) {
          notifications.error(
            m.advanced_error_set_dev_channel({ error: resp.error.data || m.unknown_error() })
          );
          return;
        }
        setDevChannel(enabled);
      });
    },
    [send, setDevChannel],
  );

  const applyLoopbackOnlyMode = useCallback(
    (enabled: boolean) => {
      send("setLocalLoopbackOnly", { enabled }, (resp: JsonRpcResponse) => {
        if ("error" in resp) {
          notifications.error(
            enabled
              ? m.advanced_error_loopback_enable({ error: resp.error.data || m.unknown_error() })
              : m.advanced_error_loopback_disable({ error: resp.error.data || m.unknown_error() })
          );
          return;
        }
        setLocalLoopbackOnly(enabled);
        if (enabled) {
          notifications.success(m.advanced_success_loopback_enabled());
        } else {
          notifications.success(m.advanced_success_loopback_disabled());
        }
      });
    },
    [send, setLocalLoopbackOnly],
  );

  const handleLoopbackOnlyModeChange = useCallback(
    (enabled: boolean) => {
      // If trying to enable loopback-only mode, show warning first
      if (enabled) {
        setShowLoopbackWarning(true);
      } else {
        // If disabling, just proceed
        applyLoopbackOnlyMode(false);
      }
    },
    [applyLoopbackOnlyMode, setShowLoopbackWarning],
  );

  const confirmLoopbackModeEnable = useCallback(() => {
    applyLoopbackOnlyMode(true);
    setShowLoopbackWarning(false);
  }, [applyLoopbackOnlyMode, setShowLoopbackWarning]);

  const handleVersionUpdate = useCallback(() => {
    const params = {
      components: {
        app: appVersion,
        system: systemVersion,
      },
      includePreRelease: devChannel,
      checkOnly: true,
    };
    send("tryUpdateComponents", params, (resp: JsonRpcResponse) => {
      if ("error" in resp) {
        notifications.error(
          m.advanced_error_version_update({ error: resp.error.data || m.unknown_error() })
        );
        return;
      }
      // Navigate to update page
      navigateTo("/settings/general/update");
    });
  }, [appVersion, systemVersion, devChannel, send, navigateTo]);

  return (
    <div className="space-y-4">
      <SettingsPageHeader
        title={m.advanced_title()}
        description={m.advanced_description()}
      />

      <div className="space-y-4">
        <SettingsItem
          title={m.advanced_dev_channel_title()}
          description={m.advanced_dev_channel_description()}
        >
          <Checkbox
            checked={devChannel}
            onChange={e => {
              handleDevChannelChange(e.target.checked);
            }}
          />
        </SettingsItem>
        <SettingsItem
          title={m.advanced_developer_mode_title()}
          description={m.advanced_developer_mode_description()}
        >
          <Checkbox
            checked={settings.developerMode}
            onChange={e => handleDevModeChange(e.target.checked)}
          />
        </SettingsItem>
        {settings.developerMode ? (
          <NestedSettingsGroup>
            <GridCard>
              <div className="flex items-start gap-x-4 p-4 select-none">
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  viewBox="0 0 24 24"
                  fill="currentColor"
                  className="mt-1 h-8 w-8 shrink-0 text-amber-600 dark:text-amber-500"
                >
                  <path
                    fillRule="evenodd"
                    d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z"
                    clipRule="evenodd"
                  />
                </svg>
                <div className="space-y-3">
                  <div className="space-y-2">
                    <h3 className="text-base font-bold text-slate-900 dark:text-white">
                      {m.advanced_developer_mode_enabled_title()}
                    </h3>
                    <div>
                      <ul className="list-disc space-y-1 pl-5 text-xs text-slate-700 dark:text-slate-300">
                        <li>{m.advanced_developer_mode_warning_security()}</li>
                        <li>{m.advanced_developer_mode_warning_risks()}</li>
                      </ul>
                    </div>
                  </div>
                  <div className="text-xs text-slate-700 dark:text-slate-300">
                    {m.advanced_developer_mode_warning_advanced()}
                  </div>
                </div>
              </div>
            </GridCard>

            {isOnDevice && (
              <div className="space-y-4">
                <SettingsItem
                  title={m.advanced_ssh_access_title()}
                  description={m.advanced_ssh_access_description()}
                />
                <TextAreaWithLabel
                  label={m.advanced_ssh_public_key_label()}
                  value={sshKey || ""}
                  rows={3}
                  onChange={e => setSSHKey(e.target.value)}
                  placeholder={m.advanced_ssh_public_key_placeholder()}
                />
                <p className="text-xs text-slate-600 dark:text-slate-400">
                  {m.advanced_ssh_default_user()}<strong>root</strong>.
                </p>
                <div className="flex items-center gap-x-2">
                  <Button
                    size="SM"
                    theme="primary"
                    text={m.advanced_update_ssh_key_button()}
                    onClick={handleUpdateSSHKey}
                  />
                </div>
              </div>
            )}

            <div className="space-y-4">
              <SettingsItem
                title={m.advanced_version_update_title()}
                description={m.advanced_version_update_description()}
              />

              <SelectMenuBasic
                label={m.advanced_version_update_target_label()}
                options={[
                  { value: "app", label: m.advanced_version_update_target_app() },
                  { value: "system", label: m.advanced_version_update_target_system() },
                  { value: "both", label: m.advanced_version_update_target_both() },
                ]}
                value={updateTarget}
                onChange={e => setUpdateTarget(e.target.value)}
              />

              {(updateTarget === "app" || updateTarget === "both") && (
                <InputFieldWithLabel
                  label={m.advanced_version_update_app_label()}
                  placeholder="0.4.9"
                  value={appVersion}
                  onChange={e => setAppVersion(e.target.value)}
                />
              )}

              {(updateTarget === "system" || updateTarget === "both") && (
                <InputFieldWithLabel
                  label={m.advanced_version_update_system_label()}
                  placeholder="0.4.9"
                  value={systemVersion}
                  onChange={e => setSystemVersion(e.target.value)}
                />
              )}

              <p className="text-xs text-slate-600 dark:text-slate-400">
                {m.advanced_version_update_helper()}{" "}
                <a
                  href="https://github.com/jetkvm/kvm/releases"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="font-medium text-blue-700 hover:underline dark:text-blue-500"
                >
                  {m.advanced_version_update_github_link()}
                </a>
              </p>

              <Button
                size="SM"
                theme="primary"
                text={m.advanced_version_update_button()}
                disabled={
                  (updateTarget === "app" && !appVersion) ||
                  (updateTarget === "system" && !systemVersion) ||
                  (updateTarget === "both" && (!appVersion || !systemVersion))
                }
                onClick={handleVersionUpdate}
              />
            </div>
          </NestedSettingsGroup>
        ) : null}

        <SettingsItem
          title={m.advanced_loopback_only_title()}
          description={m.advanced_loopback_only_description()}
        >
          <Checkbox
            checked={localLoopbackOnly}
            onChange={e => handleLoopbackOnlyModeChange(e.target.checked)}
          />
        </SettingsItem>



        <SettingsItem
          title={m.advanced_troubleshooting_mode_title()}
          description={m.advanced_troubleshooting_mode_description()}
        >
          <Checkbox
            defaultChecked={settings.debugMode}
            onChange={e => {
              settings.setDebugMode(e.target.checked);
            }}
          />
        </SettingsItem>

        {settings.debugMode && (
          <NestedSettingsGroup>
            <SettingsItem
              title={m.advanced_usb_emulation_title()}
              description={m.advanced_usb_emulation_description()}
            >
              <Button
                size="SM"
                theme="light"
                text={
                  usbEmulationEnabled ? m.advanced_disable_usb_emulation() : m.advanced_enable_usb_emulation()
                }
                onClick={() => handleUsbEmulationToggle(!usbEmulationEnabled)}
              />
            </SettingsItem>

            <SettingsItem
              title={m.advanced_reset_config_title()}
              description={m.advanced_reset_config_description()}
            >
              <Button
                size="SM"
                theme="light"
                text={m.advanced_reset_config_button()}
                onClick={async () => {
                  handleResetConfig();
                  // Add 2s delay between resetting the configuration and calling reload() to prevent reload from interrupting the RPC call to reset things.
                  await sleep(2000);
                  window.location.reload();
                }}
              />
            </SettingsItem>
          </NestedSettingsGroup>
        )}
      </div>

      <ConfirmDialog
        open={showLoopbackWarning}
        onClose={() => {
          setShowLoopbackWarning(false);
        }}
        title={m.advanced_loopback_warning_title()}
        description={
          <>
            <p>
              {m.advanced_loopback_warning_description()}
            </p>
            <p>
              {m.advanced_loopback_warning_before()}
            </p>
            <ul className="list-disc space-y-1 pl-5 text-xs text-slate-700 dark:text-slate-300">
              <li>{m.advanced_loopback_warning_ssh()}</li>
              <li>{m.advanced_loopback_warning_cloud()}</li>
            </ul>
          </>
        }
        variant="warning"
        confirmText={m.advanced_loopback_warning_confirm()}
        onConfirm={confirmLoopbackModeEnable}
      />
    </div>
  );
}
