import { Button, CssVarsProvider, Divider, Input, Select, Option } from "@mui/joy";
import { useEffect, useState } from "react";
import { Toaster, toast } from "react-hot-toast";
import { useShortcutStore } from "@/stores";
import Icon from "./components/Icon";
import Logo from "./components/Logo";
import PullShortcutsButton from "./components/PullShortcutsButton";
import ShortcutsContainer from "./components/ShortcutsContainer";
import { StorageContextProvider, useStorageContext } from "./context";
import useColorTheme from "./hooks/useColorTheme";
import "./style.css";
import { Visibility } from "./types/proto/api/v1/common";

interface SettingState {
  domain: string;
  accessToken: string;
}

const colorThemeOptions = [
  {
    value: "system",
    label: "System",
  },
  {
    value: "light",
    label: "Light",
  },
  {
    value: "dark",
    label: "Dark",
  },
];

const IndexOptions = () => {
  const { colorTheme, setColorTheme } = useColorTheme();
  const context = useStorageContext();
  const [settingState, setSettingState] = useState<SettingState>({
    domain: context.instanceUrl || "",
    accessToken: context.accessToken || "",
  });
  const shortcutStore = useShortcutStore();
  const shortcuts = shortcutStore.getShortcutList();
  const isInitialized = context.instanceUrl && context.accessToken;

  useEffect(() => {
    setSettingState({
      domain: context.instanceUrl || "",
      accessToken: context.accessToken || "",
    });
  }, [context]);

  const setPartialSettingState = (partialSettingState: Partial<SettingState>) => {
    setSettingState((prevState) => ({
      ...prevState,
      ...partialSettingState,
    }));
  };

  const handleSaveSetting = () => {
    context.setInstanceUrl(settingState.domain);
    context.setAccessToken(settingState.accessToken);
    toast.success("Setting saved");
  };

  const handleSelectColorTheme = async (colorTheme: string) => {
    setColorTheme(colorTheme as any);
  };

  const handleDefaultVisibilitySelect = (value: Visibility) => {
    context.setDefaultVisibility(value);
  };

  return (
    <div className="w-full px-4">
      <div className="w-full flex flex-row justify-center items-center">
        <a
          className="bg-yellow-100 dark:bg-yellow-500 dark:opacity-70 mt-12 py-2 px-3 rounded-full border dark:border-yellow-600 flex flex-row justify-start items-center cursor-pointer shadow hover:underline hover:text-blue-600"
          href="https://github.com/yourselfhosted/slash#browser-extension"
          target="_blank"
        >
          <Icon.HelpCircle className="w-4 h-auto" />
          <span className="mx-1 text-sm">Need help? Check out the docs</span>
          <Icon.ExternalLink className="w-4 h-auto" />
        </a>
      </div>

      <div className="w-full max-w-lg mx-auto flex flex-col justify-start items-start py-12">
        <h2 className="flex flex-row justify-start items-center mb-6 text-2xl dark:text-gray-400">
          <Logo className="w-10 h-auto mr-2" />
          <span>Slash</span>
          <span className="mx-2 text-gray-400">/</span>
          <span>Setting</span>
        </h2>

        <div className="w-full flex flex-col justify-start items-start">
          <div className="w-full flex flex-col justify-start items-start mb-4">
            <div className="mb-2 text-base w-full flex flex-row justify-between items-center">
              <span className="dark:text-gray-400">Instance URL</span>
              {context.instanceUrl !== "" && (
                <a
                  className="text-sm flex flex-row justify-start items-center underline text-blue-600 hover:opacity-80"
                  href={context.instanceUrl}
                  target="_blank"
                >
                  <span className="mr-1">Go to my Slash</span>
                  <Icon.ExternalLink className="w-4 h-auto" />
                </a>
              )}
            </div>
            <div className="relative w-full">
              <Input
                className="w-full"
                type="text"
                placeholder="The url of your Slash instance. e.g., https://slash.example.com"
                value={settingState.domain}
                onChange={(e) => setPartialSettingState({ domain: e.target.value })}
              />
            </div>
          </div>

          <div className="w-full flex flex-col justify-start items-start">
            <span className="mb-2 text-base dark:text-gray-400">Access Token</span>
            <div className="relative w-full">
              <Input
                className="w-full"
                type="text"
                placeholder="An available access token of your account."
                value={settingState.accessToken}
                onChange={(e) => setPartialSettingState({ accessToken: e.target.value })}
              />
            </div>
          </div>

          <div className="w-full mt-6 flex flex-row justify-end">
            <Button onClick={handleSaveSetting}>Save</Button>
          </div>

          <Divider className="!my-6" />

          <p className="text-base font-semibold leading-6 mb-2 text-gray-900 dark:text-gray-500">Preference</p>

          <div className="w-full flex flex-row justify-between items-center mb-2">
            <div className="flex flex-row justify-start items-center gap-x-1">
              <span className="dark:text-gray-400">Color Theme</span>
            </div>
            <Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value)}>
              {colorThemeOptions.map((option) => {
                return (
                  <Option key={option.value} value={option.value}>
                    {option.label}
                  </Option>
                );
              })}
            </Select>
          </div>

          <div className="w-full flex flex-row justify-between items-center">
            <div className="flex flex-row justify-start items-center gap-x-1">
              <span className="dark:text-gray-400">Default Visibility</span>
            </div>
            <Select defaultValue={context.defaultVisibility} onChange={(_, value) => handleDefaultVisibilitySelect(value as Visibility)}>
              <Option value={Visibility.PRIVATE}>Private</Option>
              <Option value={Visibility.WORKSPACE}>Workspace</Option>
              <Option value={Visibility.PUBLIC}>Public</Option>
            </Select>
          </div>
        </div>

        {isInitialized && (
          <>
            <Divider className="!my-6" />

            <h2 className="flex flex-row justify-start items-center mb-4">
              <span className="text-lg dark:text-gray-400">Shortcuts</span>
              <span className="text-gray-500 mr-1">({shortcuts.length})</span>
              <PullShortcutsButton />
            </h2>
            <ShortcutsContainer />
          </>
        )}
      </div>
    </div>
  );
};

const Options = () => {
  return (
    <StorageContextProvider>
      <CssVarsProvider>
        <IndexOptions />
        <Toaster position="top-center" />
      </CssVarsProvider>
    </StorageContextProvider>
  );
};

export default Options;
