import { Component, createSignal, For, Show } from "solid-js";
import { click_out_directive } from "./helper";

import { DANBOORU_API, booru_post, iqdb_search, saucenao_search, tweet_search } from "./api";
import { OTISSettingsPage } from "./settings";

import iqdb_icon from "./assets/iqdb.ico";
import sauce_icon from './assets/saucenao.ico';
import grape_icon from './assets/grapecat.png';
import danbo_icon from './assets/danbo.png';

import "./style.css";

// Typescript strips this directive if we don't 
// force call it in this module
const clickOutside = click_out_directive

type GrapeSearchParams = {
  media_url:string[],
  id:string,
  username: string
}

const GrapeCatIcon = ({onClick}:any) => <img onClick={onClick} src={grape_icon} class={"otis-icon"} title="Tweet Search" style={{"width":"20px", "margin-bottom":"2px"}}  />
const IqdbIcon     = ({onClick}:any) => <img onClick={onClick} src={iqdb_icon } class={"otis-icon"} title="Danbooru IQDB Search" />
const SauceIcon    = ({onClick}:any) => <img onClick={onClick} src={sauce_icon} class={"otis-icon"} title="SauceNAO Search" style={{"margin-right":"unset"}} />
const DanboIcon    = ({onClick}:any) => <img onClick={onClick} src={danbo_icon} class={"otis-danbo-icon"} />

async function main() {

  // check current page. Switch to Settings page instead
  const settings_page = document.URL.endsWith("/old/settings");
  if ( settings_page ) return OTISSettingsPage()

  const GrapeSearch : Component<GrapeSearchParams> = ({media_url,id, username}) => {

    const [showTooltip, setShowTooltip] = createSignal(false);
    const [ShowDanboResult, setShowDanboResult] = createSignal(false);
    const [danboPostID, setPostID ] = createSignal(0);
    const [posts, setPosts] = createSignal<Array<booru_post>>([])
    
    const booru_check = async (e:MouseEvent) => {
      //console.debug({id,username})
      //console.debug({event:e});

      const ico = e.target as HTMLImageElement;
      ico.classList.add('otis-icon-loading');
      ico.classList.remove('otis-icon-noresult');

      const res = await tweet_search(id,username)

      ico.classList.remove('otis-icon-loading');

      if ( res.length == 0 ) {
        ico.classList.add('otis-icon-noresult');
        ico.title = "Can't find any post based on Tweet ID."
        return console.debug("grape: none")
      }
      setPosts(res)

      if ( res.length === 1 ) setShowDanboResult(true)
      else setShowTooltip(true)
    }

    const iqdb_check = async (e:MouseEvent) => {

      const ico = e.target as HTMLImageElement;
      ico.classList.add('otis-icon-loading');
      ico.classList.remove('otis-icon-noresult');

      // TODO: handle which image to check
      const res = await iqdb_search(media_url[0])

      ico.classList.remove('otis-icon-loading');

      if ( res.length == 0 ) {
        ico.classList.add('otis-icon-noresult');
        ico.title = "No relevant image search results from IQDB"
        return console.debug("iqdb: none");
      }
      setPosts(res)

      if ( res.length === 1 ) setShowDanboResult(true)
      else setShowTooltip(true)
    }

    const sauce_check = async (e:MouseEvent) => {

      const ico = e.target as HTMLImageElement;
      ico.classList.add('otis-icon-loading');
      ico.classList.remove('otis-icon-noresult');

      // TODO: handle which image to check
      const res = await saucenao_search(media_url[0]);

      ico.classList.remove('otis-icon-loading');

      if ( res.length == 0 ) {
        ico.classList.add('otis-icon-noresult');
        ico.title = "No relevant image search results from IQDB"
        return console.debug("sauce: none");
      }
      setPosts(res)

      if ( res.length === 1 ) setShowDanboResult(true)
      else setShowTooltip(true)
    }

    const DanboPostsResult = () => (
      <>
        <DanboIcon />
        <a
          rel="noopener"
          target="_blank"
          class={"danbo-text-link"}
          href={`${DANBOORU_API}/posts/${posts()[0]?.id}`}
          onmouseover={() => setShowTooltip(true)}>
          {`#${posts()[0]?.id}`}
        </a>
      </>
    )

    return ( <>
      <span>
        <Show
          when={!ShowDanboResult()}
          fallback={<DanboPostsResult /> }>
          <GrapeCatIcon onClick={booru_check} />
          <IqdbIcon onClick={iqdb_check} />
          <SauceIcon onClick={sauce_check} />
        </Show>
      </span>

      <div class={"dropdown-menu danbo-more-results"} use:clickOutside={() => setShowTooltip(false)} hidden={!showTooltip()}>
        <For each={posts()}>
          { (post) =>
            <span
              class={"danbo-item"}
              onClick={() => window.open(`${DANBOORU_API}/posts/${post.id}`,'_blank')}>
              <img src={post.thumbnail} width="80px"/>
              <div>
                <div> #{post.id} </div>
                <div> {post.source_domain} </div>
                <div> { post.img_width >= 0 ? `${post.img_width} x ${post.img_height}` : ""} </div>
              </div>
            </span>
          }
        </For>
      </div>
    </>
    )
  }

  const callback : MutationCallback = (mutationList, observer) => {
    for (const mutation of mutationList) {
      if (mutation.type !== "childList") return;

      mutation.addedNodes.forEach( (node) => {

        const tweet = node as HTMLElement;
        const media = tweet.getElementsByClassName('tweet-media').item(0);
        if ( !media ) return;

        const imgs = media.getElementsByTagName('img');
        if ( !imgs ) return;

        const twt_interact = tweet.getElementsByClassName('tweet-interact').item(0);
        const twt_avatar   = tweet.getElementsByClassName('tweet-avatar-link').item(0) as HTMLAnchorElement;
        const twt_child_elipsis = twt_interact?.getElementsByClassName('tweet-interact-more').item(0);
        
        const tweet_id = tweet.dataset.tweetId || "0"
        const tweet_user = twt_avatar.href.split('/').pop() || "*"

        //console.debug({tweet_id: tweet_id, media:imgs?.length || 0});
        //console.debug({tweet_user:tweet_user});

        let img_urls = []
        for ( const img of imgs ) {
          img_urls.push(img.src)
        }
        //console.debug({media:img_urls, id:tweet_id, user:tweet_user});
        const grape = <GrapeSearch media_url={img_urls} id={tweet_id} username={tweet_user}/>;
        twt_child_elipsis?.before(...grape as any);

        // TODO: Implement OTIS buttons
      })
    }
  };


  const tweet_observer = new MutationObserver(callback);
  const timeline = document.getElementById('timeline');
  if ( !timeline ) return;
  const config: MutationObserverInit = {
    subtree:false,
    childList:true,
    attributes:false
  }
  tweet_observer.observe(timeline, config);

}


// const init:any = async (limit=0) => {
//   /* We need to do this hack because Old Twitter Extension
//      would just dump entire Twitter's page including userscripts
//      and replace it with OT's custom page instead of replacing
//      Twitter's Document Body page
//   */
  
//   if ( limit >= 10 ) return console.error("OTIS: Old Twitter Extension not detected, userscript won't run")
//   const element = document.getElementById('center-cell');
//   if (element) {
//     console.debug("Old Twitter detected");
//     return main();
//   }
//   else {
//     console.debug("can't find it");
//     await delay(1000);
//     return init(limit += 1);
//   }
// }
//init()

const element = document.getElementById('center-cell');
if (element) {
  console.debug("Old Twitter Extension detected");
  main();
}
else {
  console.debug("can't find it");
}
