/*
 This file is part of GNU Anastasis
 (C) 2021-2022 Anastasis SARL
 GNU Anastasis is free software; you can redistribute it and/or modify it under the
 terms of the GNU Affero General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.
 GNU Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
 You should have received a copy of the GNU Affero General Public License along with
 GNU Anastasis; see the file COPYING.  If not, see 
 */
/**
 *
 * @author Sebastian Javier Marchano (sebasjm)
 */
import { setupI18n } from "@gnu-taler/taler-util";
import { ComponentChild, Fragment, h, render, VNode } from "preact";
import { useEffect, useErrorBoundary, useState } from "preact/hooks";
import { strings } from "./i18n/strings.js";
import * as pages from "./pages/home/index.storiesNo.js";
const url = new URL(window.location.href);
const lang = url.searchParams.get("lang") || "en";
setupI18n(lang, strings);
const Page = ({ children }: any) => 
{children}
;
const SideBar = ({ children }: any) => ;
const Content = ({ children }: any) => {children}
;
function parseExampleImport(
  group: string,
  im: any,
  name?: string,
): ComponentItem {
  const component = name || im.default.title;
  const order: number = im.default.args?.order || 0;
  return {
    name: component,
    order,
    examples: Object.entries(im)
      .filter(([k]) => k !== "default")
      .map(
        ([name, render]) =>
          ({
            group,
            component,
            name,
            render,
          } as ExampleItem),
      ),
  };
}
function SortStories(a: any, b: any): number {
  return (a?.order ?? 0) - (b?.order ?? 0);
}
const allExamples = Object.entries({ pages }).map(([title, value]) => {
  return {
    title,
    list: Object.entries(value)
      .filter(([name]) => name != "default")
      .map(([name, value]) => parseExampleImport(title, value, name))
      .sort(SortStories),
  };
});
interface ComponentItem {
  name: string;
  order: number;
  examples: ExampleItem[];
}
interface ExampleItem {
  group: string;
  component: string;
  name: string;
  render: {
    (args: any): VNode;
    args: any;
  };
}
function findByGroupComponentName(
  group: string,
  component: string,
  name: string,
): ExampleItem | undefined {
  const gl = allExamples.filter((e) => e.title === group);
  if (gl.length === 0) {
    return undefined;
  }
  const cl = gl[0].list.filter((l) => l.name === component);
  if (cl.length === 0) {
    return undefined;
  }
  const el = cl[0].examples.filter((c) => c.name === name);
  if (el.length === 0) {
    return undefined;
  }
  return el[0];
}
function getContentForExample(item: ExampleItem | undefined): () => VNode {
  if (!item)
    return function SelectExampleMessage() {
      return select example from the list on the left
;
    };
  const example = findByGroupComponentName(
    item.group,
    item.component,
    item.name,
  );
  if (!example)
    return function ExampleNotFoundMessage() {
      return example not found
;
    };
  return () => example.render(example.render.args);
}
function ExampleList({
  name,
  list,
  selected,
  onSelectStory,
}: {
  name: string;
  list: {
    name: string;
    examples: ExampleItem[];
  }[];
  selected: ExampleItem | undefined;
  onSelectStory: (i: ExampleItem, id: string) => void;
}): VNode {
  const [isOpen, setOpen] = useState(selected && selected.group === name);
  return (
    
       setOpen(!isOpen)}>{name}
      
        {list.map((k) => (
          
- 
            
              - {k.name}{k.examples.map((r) => {
                const e = encodeURIComponent;
                const eId = `${e(r.group)}-${e(r.component)}-${e(r.name)}`;
                function doSelection(e: any): void {
                  e.preventDefault();
                  location.hash = `#${eId}`;
                  onSelectStory(r, eId);
                }
                const isSelected =
                  selected &&
                  selected.component === r.component &&
                  selected.group === r.group &&
                  selected.name === r.name;
                return (
- 
                    
                      {r.name}
                    
                  );
              })}
 
        ))}
      
);
}
// function getWrapperForGroup(group: string): FunctionComponent {
//   switch (group) {
//     case "popup":
//       return function PopupWrapper({ children }: any) {
//         return (
//           
//             
//             {children}
//           
//         );
//       };
//     case "wallet":
//       return function WalletWrapper({ children }: any) {
//         return (
//           
//             
//             
//             {children}
//           
//         );
//       };
//     case "cta":
//       return function WalletWrapper({ children }: any) {
//         return (
//           
//             {children}
//           
//         );
//       };
//     default:
//       return Fragment;
//   }
// }
function ErrorReport({
  children,
  selected,
}: {
  children: ComponentChild;
  selected: ExampleItem | undefined;
}): VNode {
  const [error] = useErrorBoundary();
  if (error) {
    return (
        Error was thrown trying to render
        {selected && (
          
        )}
        
{error.message}
        {error.stack}
       
    );
  }
  return {children};
}
function getSelectionFromLocationHash(hash: string): ExampleItem | undefined {
  if (!hash) return undefined;
  const parts = hash.substring(1).split("-");
  if (parts.length < 3) return undefined;
  return findByGroupComponentName(
    decodeURIComponent(parts[0]),
    decodeURIComponent(parts[1]),
    decodeURIComponent(parts[2]),
  );
}
function Application(): VNode {
  const initialSelection = getSelectionFromLocationHash(location.hash);
  const [selected, updateSelected] = useState(
    initialSelection,
  );
  useEffect(() => {
    if (location.hash) {
      const hash = location.hash.substring(1);
      const found = document.getElementById(hash);
      if (found) {
        setTimeout(() => {
          found.scrollIntoView({
            block: "center",
          });
        }, 10);
      }
    }
  }, []);
  const ExampleContent = getContentForExample(selected);
  // const GroupWrapper = getWrapperForGroup(selected?.group || "default");
  return (
    
      
      
        {allExamples.map((e) => (
           {
              document.getElementById(htmlId)?.scrollIntoView({
                block: "center",
              });
              updateSelected(item);
            }}
          />
        ))}
        
      
      
        
          {/*  */}
          
          {/*  */}
        
      
    
  );
}
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", main);
} else {
  main();
}
function main(): void {
  try {
    const container = document.getElementById("container");
    if (!container) {
      throw Error("container not found, can't mount page contents");
    }
    render(, container);
  } catch (e) {
    console.error("got error", e);
    if (e instanceof Error) {
      document.body.innerText = `Fatal error: "${e.message}".  Please report this bug at https://bugs.gnunet.org/.`;
    }
  }
}
let liveReloadMounted = false;
function LiveReload({ port = 8002 }: { port?: number }): VNode {
  const [isReloading, setIsReloading] = useState(false);
  useEffect(() => {
    if (!liveReloadMounted) {
      setupLiveReload(port, () => {
        setIsReloading(true);
        window.location.reload();
      });
      liveReloadMounted = true;
    }
  });
  if (isReloading) {
    return (
      
        
reloading...
      
    );
  }
  return ;
}
function setupLiveReload(port: number, onReload: () => void): void {
  const socketPath = `ws://localhost:8003/socket`;
  // const socketPath = `${protocol}//${host}:${port}/socket`;
  const ws = new WebSocket(socketPath);
  ws.onmessage = (message) => {
    const event = JSON.parse(message.data);
    if (event.type === "LOG") {
      console.log(event.message);
    }
    if (event.type === "RELOAD") {
      onReload();
    }
  };
  ws.onerror = (error) => {
    console.error(error);
  };
  ws.onclose = (e) => {
    console.log("disconnected", e);
  };
}