import { useState, useEffect, useMemo } from "react";
import styles from "./settings.module.scss";
import ResetIcon from "../icons/reload.svg";
import AddIcon from "../icons/add.svg";
import CloseIcon from "../icons/close.svg";
import CopyIcon from "../icons/copy.svg";
import ClearIcon from "../icons/clear.svg";
import LoadingIcon from "../icons/three-dots.svg";
import EditIcon from "../icons/edit.svg";
import FireIcon from "../icons/fire.svg";
import EyeIcon from "../icons/eye.svg";
import DownloadIcon from "../icons/download.svg";
import UploadIcon from "../icons/upload.svg";
import ConfigIcon from "../icons/config.svg";
import ConfirmIcon from "../icons/confirm.svg";
import ConnectionIcon from "../icons/connection.svg";
import CloudSuccessIcon from "../icons/cloud-success.svg";
import CloudFailIcon from "../icons/cloud-fail.svg";
import { trackSettingsPageGuideToCPaymentClick } from "../utils/auth-settings-events";
import {
  Input,
  List,
  ListItem,
  Modal,
  PasswordInput,
  Popover,
  Select,
  showConfirm,
  showToast,
} from "./ui-lib";
import { ModelConfigList } from "./model-config";
import { IconButton } from "./button";
import {
  SubmitKey,
  useChatStore,
  Theme,
  useUpdateStore,
  useAccessStore,
  useAppConfig,
} from "../store";
import Locale, {
  AllLangs,
  ALL_LANG_OPTIONS,
  changeLang,
  getLang,
} from "../locales";
import { copyToClipboard } from "../utils";
import Link from "next/link";
import {
  Anthropic,
  Azure,
  Baidu,
  Tencent,
  ByteDance,
  Alibaba,
  Moonshot,
  Google,
  GoogleSafetySettingsThreshold,
  OPENAI_BASE_URL,
  Path,
  RELEASE_URL,
  STORAGE_KEY,
  ServiceProvider,
  SlotID,
  UPDATE_URL,
  Stability,
  Iflytek,
  SAAS_CHAT_URL,
} from "../constant";
import { Prompt, SearchService, usePromptStore } from "../store/prompt";
import { ErrorBoundary } from "./error";
import { InputRange } from "./input-range";
import { useNavigate } from "react-router-dom";
import { Avatar, AvatarPicker } from "./emoji";
import { getClientConfig } from "../config/client";
import { useSyncStore } from "../store/sync";
import { nanoid } from "nanoid";
import { useMaskStore } from "../store/mask";
import { ProviderType } from "../utils/cloud";
import { TTSConfigList } from "./tts-config";
function EditPromptModal(props: { id: string; onClose: () => void }) {
  const promptStore = usePromptStore();
  const prompt = promptStore.get(props.id);
  return prompt ? (
    
  ) : null;
}
function UserPromptModal(props: { onClose?: () => void }) {
  const promptStore = usePromptStore();
  const userPrompts = promptStore.getUserPrompts();
  const builtinPrompts = SearchService.builtinPrompts;
  const allPrompts = userPrompts.concat(builtinPrompts);
  const [searchInput, setSearchInput] = useState("");
  const [searchPrompts, setSearchPrompts] = useState([]);
  const prompts = searchInput.length > 0 ? searchPrompts : allPrompts;
  const [editingPromptId, setEditingPromptId] = useState();
  useEffect(() => {
    if (searchInput.length > 0) {
      const searchResult = SearchService.search(searchInput);
      setSearchPrompts(searchResult);
    } else {
      setSearchPrompts([]);
    }
  }, [searchInput]);
  return (
    
       props.onClose?.()}
        actions={[
           {
              const promptId = promptStore.add({
                id: nanoid(),
                createdAt: Date.now(),
                title: "Empty Prompt",
                content: "Empty Prompt Content",
              });
              setEditingPromptId(promptId);
            }}
            icon={}
            bordered
            text={Locale.Settings.Prompt.Modal.Add}
          />,
        ]}
      >
        
           setSearchInput(e.currentTarget.value)}
          >
          
            {prompts.map((v, _) => (
              
                
                
                  {v.isUser && (
                    }
                      className={styles["user-prompt-button"]}
                      onClick={() => promptStore.remove(v.id!)}
                    />
                  )}
                  {v.isUser ? (
                    }
                      className={styles["user-prompt-button"]}
                      onClick={() => setEditingPromptId(v.id)}
                    />
                  ) : (
                    }
                      className={styles["user-prompt-button"]}
                      onClick={() => setEditingPromptId(v.id)}
                    />
                  )}
                  }
                    className={styles["user-prompt-button"]}
                    onClick={() => copyToClipboard(v.content)}
                  />
                
               
            ))}
          
 
      
      {editingPromptId !== undefined && (
        
 setEditingPromptId(undefined)}
        />
      )}
     
  );
}
function DangerItems() {
  const chatStore = useChatStore();
  const appConfig = useAppConfig();
  return (
    
      
         {
            if (await showConfirm(Locale.Settings.Danger.Reset.Confirm)) {
              appConfig.reset();
            }
          }}
          type="danger"
        />
      
      
         {
            if (await showConfirm(Locale.Settings.Danger.Clear.Confirm)) {
              chatStore.clearAllData();
            }
          }}
          type="danger"
        />
      
    
);
}
function CheckButton() {
  const syncStore = useSyncStore();
  const couldCheck = useMemo(() => {
    return syncStore.cloudSync();
  }, [syncStore]);
  const [checkState, setCheckState] = useState<
    "none" | "checking" | "success" | "failed"
  >("none");
  async function check() {
    setCheckState("checking");
    const valid = await syncStore.check();
    setCheckState(valid ? "success" : "failed");
  }
  if (!couldCheck) return null;
  return (
    
        ) : checkState === "checking" ? (
          
        ) : checkState === "success" ? (
          
        ) : checkState === "failed" ? (
          
        ) : (
          
        )
      }
    >
  );
}
function SyncConfigModal(props: { onClose?: () => void }) {
  const syncStore = useSyncStore();
  return (
       props.onClose?.()}
        actions={[
          ,
          }
            bordered
            text={Locale.UI.Confirm}
          />,
        ]}
      >
        
          
            
          
          
             {
                syncStore.update(
                  (config) => (config.useProxy = e.currentTarget.checked),
                );
              }}
            >
          
          {syncStore.useProxy ? (
            
               {
                  syncStore.update(
                    (config) => (config.proxyUrl = e.currentTarget.value),
                  );
                }}
              >
            
          ) : null}
        
{syncStore.provider === ProviderType.WebDAV && (
          <>
              
                 {
                    syncStore.update(
                      (config) =>
                        (config.webdav.endpoint = e.currentTarget.value),
                    );
                  }}
                >
              
              
                 {
                    syncStore.update(
                      (config) =>
                        (config.webdav.username = e.currentTarget.value),
                    );
                  }}
                >
              
              
                 {
                    syncStore.update(
                      (config) =>
                        (config.webdav.password = e.currentTarget.value),
                    );
                  }}
                >
              
            
>
        )}
        {syncStore.provider === ProviderType.UpStash && (
            
               {
                  syncStore.update(
                    (config) =>
                      (config.upstash.endpoint = e.currentTarget.value),
                  );
                }}
              >
            
            
               {
                  syncStore.update(
                    (config) =>
                      (config.upstash.username = e.currentTarget.value),
                  );
                }}
              >
            
            
               {
                  syncStore.update(
                    (config) => (config.upstash.apiKey = e.currentTarget.value),
                  );
                }}
              >
            
          
)} 
  );
}
function SyncItems() {
  const syncStore = useSyncStore();
  const chatStore = useChatStore();
  const promptStore = usePromptStore();
  const maskStore = useMaskStore();
  const couldSync = useMemo(() => {
    return syncStore.cloudSync();
  }, [syncStore]);
  const [showSyncConfigModal, setShowSyncConfigModal] = useState(false);
  const stateOverview = useMemo(() => {
    const sessions = chatStore.sessions;
    const messageCount = sessions.reduce((p, c) => p + c.messages.length, 0);
    return {
      chat: sessions.length,
      message: messageCount,
      prompt: Object.keys(promptStore.prompts).length,
      mask: Object.keys(maskStore.masks).length,
    };
  }, [chatStore.sessions, maskStore.masks, promptStore.prompts]);
  return (
    <>
      
        
          
            }
              text={Locale.UI.Config}
              onClick={() => {
                setShowSyncConfigModal(true);
              }}
            />
            {couldSync && (
              }
                text={Locale.UI.Sync}
                onClick={async () => {
                  try {
                    await syncStore.sync();
                    showToast(Locale.Settings.Sync.Success);
                  } catch (e) {
                    showToast(Locale.Settings.Sync.Fail);
                    console.error("[Sync]", e);
                  }
                }}
              />
            )}
          
        
        
          
            }
              text={Locale.UI.Export}
              onClick={() => {
                syncStore.export();
              }}
            />
            }
              text={Locale.UI.Import}
              onClick={() => {
                syncStore.import();
              }}
            />
          
        
      
{showSyncConfigModal && (
         setShowSyncConfigModal(false)} />
      )}
    >
  );
}
export function Settings() {
  const navigate = useNavigate();
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const config = useAppConfig();
  const updateConfig = config.update;
  const updateStore = useUpdateStore();
  const [checkingUpdate, setCheckingUpdate] = useState(false);
  const currentVersion = updateStore.formatVersion(updateStore.version);
  const remoteId = updateStore.formatVersion(updateStore.remoteVersion);
  const hasNewVersion = currentVersion !== remoteId;
  const updateUrl = getClientConfig()?.isApp ? RELEASE_URL : UPDATE_URL;
  function checkUpdate(force = false) {
    setCheckingUpdate(true);
    updateStore.getLatestVersion(force).then(() => {
      setCheckingUpdate(false);
    });
    console.log("[Update] local version ", updateStore.version);
    console.log("[Update] remote version ", updateStore.remoteVersion);
  }
  const accessStore = useAccessStore();
  const shouldHideBalanceQuery = useMemo(() => {
    const isOpenAiUrl = accessStore.openaiUrl.includes(OPENAI_BASE_URL);
    return (
      accessStore.hideBalanceQuery ||
      isOpenAiUrl ||
      accessStore.provider === ServiceProvider.Azure
    );
  }, [
    accessStore.hideBalanceQuery,
    accessStore.openaiUrl,
    accessStore.provider,
  ]);
  const usage = {
    used: updateStore.used,
    subscription: updateStore.subscription,
  };
  const [loadingUsage, setLoadingUsage] = useState(false);
  function checkUsage(force = false) {
    if (shouldHideBalanceQuery) {
      return;
    }
    setLoadingUsage(true);
    updateStore.updateUsage(force).finally(() => {
      setLoadingUsage(false);
    });
  }
  const enabledAccessControl = useMemo(
    () => accessStore.enabledAccessControl(),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [],
  );
  const promptStore = usePromptStore();
  const builtinCount = SearchService.count.builtin;
  const customCount = promptStore.getUserPrompts().length ?? 0;
  const [shouldShowPromptModal, setShowPromptModal] = useState(false);
  const showUsage = accessStore.isAuthorized();
  useEffect(() => {
    // checks per minutes
    checkUpdate();
    showUsage && checkUsage();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  useEffect(() => {
    const keydownEvent = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        navigate(Path.Home);
      }
    };
    if (clientConfig?.isApp) {
      // Force to set custom endpoint to true if it's app
      accessStore.update((state) => {
        state.useCustomConfig = true;
      });
    }
    document.addEventListener("keydown", keydownEvent);
    return () => {
      document.removeEventListener("keydown", keydownEvent);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
  const clientConfig = useMemo(() => getClientConfig(), []);
  const showAccessCode = enabledAccessControl && !clientConfig?.isApp;
  const accessCodeComponent = showAccessCode && (
    
       {
          accessStore.update(
            (access) => (access.accessCode = e.currentTarget.value),
          );
        }}
      />
    
  );
  const saasStartComponent = (
    
      }
        type={"primary"}
        text={Locale.Settings.Access.SaasStart.ChatNow}
        onClick={() => {
          trackSettingsPageGuideToCPaymentClick();
          window.location.href = SAAS_CHAT_URL;
        }}
      />
    
  );
  const useCustomConfigComponent = // Conditionally render the following ListItem based on clientConfig.isApp
    !clientConfig?.isApp && ( // only show if isApp is false
      
        
            accessStore.update(
              (access) => (access.useCustomConfig = e.currentTarget.checked),
            )
          }
        >
      
    );
  const openAIConfigComponent = accessStore.provider ===
    ServiceProvider.OpenAI && (
    <>
      
        
            accessStore.update(
              (access) => (access.openaiUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.openaiApiKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const azureConfigComponent = accessStore.provider ===
    ServiceProvider.Azure && (
    <>
      
        
            accessStore.update(
              (access) => (access.azureUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.azureApiKey = e.currentTarget.value),
            );
          }}
        />
      
      
        
            accessStore.update(
              (access) => (access.azureApiVersion = e.currentTarget.value),
            )
          }
        >
      
    >
  );
  const googleConfigComponent = accessStore.provider ===
    ServiceProvider.Google && (
    <>
      
        
            accessStore.update(
              (access) => (access.googleUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.googleApiKey = e.currentTarget.value),
            );
          }}
        />
      
      
        
            accessStore.update(
              (access) => (access.googleApiVersion = e.currentTarget.value),
            )
          }
        >
      
      
        
      
    >
  );
  const anthropicConfigComponent = accessStore.provider ===
    ServiceProvider.Anthropic && (
    <>
      
        
            accessStore.update(
              (access) => (access.anthropicUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.anthropicApiKey = e.currentTarget.value),
            );
          }}
        />
      
      
        
            accessStore.update(
              (access) => (access.anthropicApiVersion = e.currentTarget.value),
            )
          }
        >
      
    >
  );
  const baiduConfigComponent = accessStore.provider ===
    ServiceProvider.Baidu && (
    <>
      
        
            accessStore.update(
              (access) => (access.baiduUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.baiduApiKey = e.currentTarget.value),
            );
          }}
        />
      
      
         {
            accessStore.update(
              (access) => (access.baiduSecretKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const tencentConfigComponent = accessStore.provider ===
    ServiceProvider.Tencent && (
    <>
      
        
            accessStore.update(
              (access) => (access.tencentUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.tencentSecretId = e.currentTarget.value),
            );
          }}
        />
      
      
         {
            accessStore.update(
              (access) => (access.tencentSecretKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const byteDanceConfigComponent = accessStore.provider ===
    ServiceProvider.ByteDance && (
    <>
      
        
            accessStore.update(
              (access) => (access.bytedanceUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.bytedanceApiKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const alibabaConfigComponent = accessStore.provider ===
    ServiceProvider.Alibaba && (
    <>
      
        
            accessStore.update(
              (access) => (access.alibabaUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.alibabaApiKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const moonshotConfigComponent = accessStore.provider ===
    ServiceProvider.Moonshot && (
    <>
      
        
            accessStore.update(
              (access) => (access.moonshotUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.moonshotApiKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const stabilityConfigComponent = accessStore.provider ===
    ServiceProvider.Stability && (
    <>
      
        
            accessStore.update(
              (access) => (access.stabilityUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.stabilityApiKey = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  const lflytekConfigComponent = accessStore.provider ===
    ServiceProvider.Iflytek && (
    <>
      
        
            accessStore.update(
              (access) => (access.iflytekUrl = e.currentTarget.value),
            )
          }
        >
      
      
         {
            accessStore.update(
              (access) => (access.iflytekApiKey = e.currentTarget.value),
            );
          }}
        />
      
      
         {
            accessStore.update(
              (access) => (access.iflytekApiSecret = e.currentTarget.value),
            );
          }}
        />
      
    >
  );
  return (
        
          
            {Locale.Settings.Title}
          
          
            {Locale.Settings.SubTitle}
          
         
        
          
          
          
            }
              onClick={() => navigate(Path.Home)}
              bordered
            />
          
         
       
      
        
          
             setShowEmojiPicker(false)}
              content={
                 {
                    updateConfig((config) => (config.avatar = avatar));
                    setShowEmojiPicker(false);
                  }}
                />
              }
              open={showEmojiPicker}
            >
               {
                  setShowEmojiPicker(!showEmojiPicker);
                }}
              >
                
              
          
            
                updateConfig(
                  (config) =>
                    (config.dontShowMaskSplashScreen =
                      !e.currentTarget.checked),
                )
              }
            >
          
          
            
                updateConfig(
                  (config) =>
                    (config.hideBuiltinMasks = e.currentTarget.checked),
                )
              }
            >
          
        
          
            
                updateConfig(
                  (config) =>
                    (config.disablePromptHint = e.currentTarget.checked),
                )
              }
            >
          
          
            }
              text={Locale.Settings.Prompt.Edit}
              onClick={() => setShowPromptModal(true)}
            />
          
        
          {saasStartComponent}
          {accessCodeComponent}
          {!accessStore.hideUserApiKey && (
            <>
              {useCustomConfigComponent}
              {accessStore.useCustomConfig && (
                <>
                  
                    
                  
                  {openAIConfigComponent}
                  {azureConfigComponent}
                  {googleConfigComponent}
                  {anthropicConfigComponent}
                  {baiduConfigComponent}
                  {byteDanceConfigComponent}
                  {alibabaConfigComponent}
                  {tencentConfigComponent}
                  {moonshotConfigComponent}
                  {stabilityConfigComponent}
                  {lflytekConfigComponent}
                >
              )}
            >
          )}
          {!shouldHideBalanceQuery && !clientConfig?.isApp ? (
            
              {!showUsage || loadingUsage ? (
                
              ) : (
                }
                  text={Locale.Settings.Usage.Check}
                  onClick={() => checkUsage(true)}
                />
              )}
            
          ) : null}
          
            
                config.update(
                  (config) => (config.customModels = e.currentTarget.value),
                )
              }
            >
          
        
           {
              const modelConfig = { ...config.modelConfig };
              updater(modelConfig);
              config.update((config) => (config.modelConfig = modelConfig));
            }}
          />
        
        {shouldShowPromptModal && (
          
 setShowPromptModal(false)} />
        )}
        
           {
              const ttsConfig = { ...config.ttsConfig };
              updater(ttsConfig);
              config.update((config) => (config.ttsConfig = ttsConfig));
            }}
          />
        
 
    
  );
}