import {
  For,
  Show,
  type Component,
} from "solid-js";
import Scaffold from "../material/Scaffold.js";
import {
  AppBar,
  Divider,
  IconButton,
  List,
  ListItem,
  ListItemButton,
  ListItemIcon,
  ListItemSecondaryAction,
  ListItemText,
  ListSubheader,
  NativeSelect,
  Switch,
  Toolbar,
} from "@suid/material";
import {
  Animation as AnimationIcon,
  Close as CloseIcon,
  Logout,
  Public as PublicIcon,
  Refresh as RefreshIcon,
  Translate as TranslateIcon,
} from "@suid/icons-material";
import A from "../platform/A.js";
import { Title } from "../material/typography.jsx";
import { css } from "solid-styled";
import { signOut, type Account } from "../accounts/stores.js";
import { format } from "date-fns";
import { useStore } from "@nanostores/solid";
import { $settings } from "./stores.js";
import {
  autoMatchLangTag,
  autoMatchRegion,
  createTranslator,
  useDateFnLocale,
} from "../platform/i18n.jsx";
import { type Template } from "@solid-primitives/i18n";
import { useServiceWorker } from "../platform/host.js";
import { useSessions } from "../masto/clients.js";
import { useNavigator } from "../platform/StackedRouter.jsx";

type Inset = {
  top?: number;
  right?: number;
  bottom?: number;
  left?: number;
};

type SafeAreaInsets = {
  landscape: Inset;
  protrait: Inset;
};

const safeAreaInsets: Record<string, SafeAreaInsets> = {
  iphone15: {
    protrait: {
      top: 59,
      bottom: 34,
    },
    landscape: {
      bottom: 21,
      left: 59,
      right: 59,
    },
  },
  iphone12: {
    protrait: {
      top: 47,
      bottom: 34,
    },
    landscape: {
      bottom: 21,
      left: 47,
      right: 47,
    },
  },
  iphone13mini: {
    protrait: {
      top: 50,
      bottom: 34,
    },
    landscape: {
      bottom: 21,
      left: 50,
      right: 50,
    },
  },
};

let screenOrientationCallback: (() => void) | undefined;

function removeSafeAreaEmulation(root: HTMLElement) {
  for (const name of ["top", "right", "bottom", "left"]) {
    root.style.removeProperty(`--safe-area-inset-${name}`);
  }
}

function applySafeAreaEmulation(root: HTMLElement, insets: Inset) {
  removeSafeAreaEmulation(root);
  for (const key of Object.keys(insets) as (keyof Inset)[]) {
    const value = insets[key];
    if (!value || value === 0) continue;
    root.style.setProperty(`--safe-area-inset-${key}`, `${value}px`);
  }
}

function setupSafeAreaEmulation(name: string) {
  const insets = safeAreaInsets[name];
  const root = document.querySelector(":root")! as HTMLElement;

  if (screenOrientationCallback) {
    window.screen.orientation.removeEventListener(
      "change",
      screenOrientationCallback,
    );
    screenOrientationCallback = undefined;
  }

  removeSafeAreaEmulation(root);

  if (insets) {
    screenOrientationCallback = () => {
      console.debug(
        `safe area emulation target: ${window.screen.orientation.type}`,
      );
      if (window.screen.orientation.type === "portrait-primary") {
        console.debug("safe area emulation: protrait");
        applySafeAreaEmulation(root, insets.protrait);
      } else if (window.screen.orientation.type === "landscape-primary") {
        console.debug("safe area emulation: landscape");
        applySafeAreaEmulation(root, insets.landscape);
      }
    };
    window.screen.orientation.addEventListener(
      "change",
      screenOrientationCallback,
    );
    screenOrientationCallback();
  }
}

if (import.meta.hot) {
  import.meta.hot.accept((mod) => {
    if (!mod) return;
    if (screenOrientationCallback) {
      mod["screenOrientationCallback"] = screenOrientationCallback;
      setTimeout(screenOrientationCallback, 0);
    }
  });
}

type Strings = {
  ["lang.auto"]: Template<{ detected: string }>;
} & Record<string, string | undefined>;

const Settings: Component = () => {
  const [t] = createTranslator(
    (code) =>
      import(`./i18n/${code}.json`) as Promise<{
        default: Strings;
      }>,
    () => import(`./i18n/lang-names.json`),
  );
  const {pop} = useNavigator();
  const settings$ = useStore($settings);
  const { needRefresh } = useServiceWorker();
  const dateFnLocale = useDateFnLocale();

  const profiles = useSessions();

  const doSignOut = (acct: Account) => {
    signOut((a) => a.site === acct.site && a.accessToken === acct.accessToken);
  };

  css`
    ul {
      padding: 0;
    }

    .setting-list {
      padding-bottom: calc(var(--safe-area-inset-bottom, 0px) + 16px);
    }
  `;
  return (
    <Scaffold
      topbar={
        <AppBar position="static">
          <Toolbar
            variant="dense"
            sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
          >
            <IconButton color="inherit" onClick={[pop, 1]} disableRipple>
              <CloseIcon />
            </IconButton>
            <Title>{t("Settings")}</Title>
          </Toolbar>
        </AppBar>
      }
    >
      <List class="setting-list" use:solid-styled>
        <li>
          <ul>
            <ListSubheader>{t("Accounts")}</ListSubheader>
            <ListItemButton disabled>
              <ListItemText>{t("All Notifications")}</ListItemText>
              <ListItemSecondaryAction>
                <Switch value={false} disabled />
              </ListItemSecondaryAction>
            </ListItemButton>
            <Divider />
            <ListItemButton disabled>
              <ListItemText>{t("Sign in...")}</ListItemText>
            </ListItemButton>
            <Divider />
          </ul>
          <For each={profiles()}>
            {({ account: acct }) => (
              <ul data-site={acct.site} data-username={acct.inf?.username}>
                <ListSubheader>{`@${acct.inf?.username ?? "..."}@${new URL(acct.site).host}`}</ListSubheader>
                <ListItemButton disabled>
                  <ListItemText>{t("Notifications")}</ListItemText>
                  <ListItemSecondaryAction>
                    <Switch value={false} disabled />
                  </ListItemSecondaryAction>
                </ListItemButton>
                <Divider />
                <ListItemButton onClick={[doSignOut, acct]}>
                  <ListItemIcon>
                    <Logout />
                  </ListItemIcon>
                  <ListItemText>{t("Sign out")}</ListItemText>
                </ListItemButton>
                <Divider />
              </ul>
            )}
          </For>
        </li>
        <li>
          <ListSubheader>{t("timelines")}</ListSubheader>
          <ListItemButton
            onClick={(e) =>
              $settings.setKey(
                "prefetchTootsDisabled",
                !settings$().prefetchTootsDisabled,
              )
            }
          >
            <ListItemText secondary={t("Prefetch Toots.2nd")}>
              {t("Prefetch Toots")}
            </ListItemText>
            <ListItemSecondaryAction>
              <Switch checked={!settings$().prefetchTootsDisabled} />
            </ListItemSecondaryAction>
          </ListItemButton>
          <Divider />
          <ListItemButton component={A} href="./motions">
            <ListItemIcon>
              <AnimationIcon></AnimationIcon>
            </ListItemIcon>
            <ListItemText>{t("motions")}</ListItemText>
          </ListItemButton>
          <Divider />
        </li>
        <li>
          <ListSubheader>{t("This Application")}</ListSubheader>
          <ListItemButton component={A} href="./language">
            <ListItemIcon>
              <TranslateIcon />
            </ListItemIcon>
            <ListItemText
              secondary={
                settings$().language === undefined
                  ? t("lang.auto", {
                      detected:
                        t("lang." + autoMatchLangTag()) ?? autoMatchLangTag(),
                    })
                  : t("lang." + settings$().language)
              }
            >
              {t("Language")}
            </ListItemText>
          </ListItemButton>
          <Divider />
          <ListItemButton component={A} href="./region">
            <ListItemIcon>
              <PublicIcon />
            </ListItemIcon>
            <ListItemText
              secondary={
                settings$().region === undefined
                  ? t("region.auto", {
                      detected:
                        t("region." + autoMatchRegion()) ?? autoMatchRegion(),
                    })
                  : t("region." + settings$().region)
              }
            >
              {t("Region")}
            </ListItemText>
          </ListItemButton>
          <Divider />
          <ListItem>
            <ListItemText secondary={t("About Tutu.2nd")}>
              {t("About Tutu")}
            </ListItemText>
          </ListItem>
          <Divider />
          <ListItem>
            <ListItemText
              secondary={t("version", {
                packageVersion: import.meta.env.PACKAGE_VERSION,
                builtAt: format(
                  import.meta.env.BUILT_AT,
                  t("datefmt") || "yyyy/MM/dd",
                  { locale: dateFnLocale() },
                ),
                buildMode: import.meta.env.MODE,
              })}
            >
              {needRefresh() ? t("updates.ready") : t("updates.no")}
            </ListItemText>
            <Show when={needRefresh()}>
              <ListItemSecondaryAction>
                <IconButton
                  aria-label="Restart Now"
                  onClick={() => window.location.reload()}
                >
                  <RefreshIcon />
                </IconButton>
              </ListItemSecondaryAction>
            </Show>
          </ListItem>
          <Divider />
          {import.meta.env.VITE_CODE_VERSION ? (
            <>
              <ListItem>
                <ListItemText secondary={import.meta.env.VITE_CODE_VERSION}>
                  {t("version.code")}
                </ListItemText>
              </ListItem>
              <Divider />
            </>
          ) : (
            <></>
          )}
        </li>
        {import.meta.env.DEV ? (
          <li>
            <ListSubheader>Developer Tools</ListSubheader>
            <ListItem
              secondaryAction={
                window.screen?.orientation ? (
                  <NativeSelect
                    sx={{ maxWidth: "40vw" }}
                    onChange={(event) => {
                      const k = event.currentTarget.value;
                      setupSafeAreaEmulation(k);
                    }}
                  >
                    <option>Don't change</option>
                    <option value={"ua"}>User agent</option>
                    <option value={"iphone15"}>
                      iPhone 15 and Plus, Pro, Pro Max
                    </option>
                    <option value={"iphone12"}>iPhone 12, 13 and 14</option>
                    <option value={"iphone13mini"}>iPhone 13 mini</option>
                  </NativeSelect>
                ) : undefined
              }
            >
              <ListItemText
                secondary={
                  window.screen?.orientation
                    ? undefined
                    : "Unsupported on This Platform"
                }
              >
                Safe Area Insets
              </ListItemText>
            </ListItem>
            <Divider />
          </li>
        ) : (
          <></>
        )}
      </List>
    </Scaffold>
  );
};

export default Settings;
