"use client";
import Image from "next/image";
import { useSearchParams } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import { Unity, UnityConfig, useUnityContext } from "react-unity-webgl";
import { ObjectType } from "../types";
const unityConfigBuilder = (path: string): UnityConfig => ({
  loaderUrl: `${path}.loader.js`,
  dataUrl: `${path}.data`,
  frameworkUrl: `${path}.framework.js`,
  codeUrl: `${path}.wasm`,
  streamingAssetsUrl: "StreamingAssets",
  companyName: "DTOL",
  productName: "3d-test",
  productVersion: "0.1",
});

export default function UnityComponent({
  option = [],
  ohg = [],
  frame = [],
}: {
  option: {
    value: string;
    name: string;
    description: string;
  }[];
  ohg: ObjectType[];
  frame: ObjectType[];
}) {
  const params = useSearchParams();
  const p = params.get("p");
  const [selectedIndex, setSelectedIndex] = useState({ ohg: 0, frame: 0 });
  type SelectedIndexType = typeof selectedIndex;
  const [match, setMatch] = useState(100);
  if (!p || isNaN(Number(p))) location.href = "/unity?p=0";

  const { unityProvider, isLoaded, loadingProgression, UNSAFE__unityInstance } =
    useUnityContext(unityConfigBuilder(option[Number(p)].value));

  const loadingPercentage = Math.round(loadingProgression * 100);

  // 매치율 조회 및 업데이트
  const handleMatchUpdate = useCallback(
    async (newSelectedIndex: SelectedIndexType) => {
      const res = await fetch(
        `/fit?o=${newSelectedIndex.ohg}&f=${newSelectedIndex.frame}`,
        {
          method: "GET",
        },
      );
      console.log(res);
      const json = (await res.json()) as { match: number };
      if (isNaN(Number(json.match)) === false) setMatch(json.match);
      return json.match;
    },
    [],
  );

  // 최초 1회 조회
  useEffect(() => {
    handleMatchUpdate({ ohg: 0, frame: 0 });
  }, [handleMatchUpdate]);

  // ohg나 frame이 바뀔 때마다 호출
  const handleSelectIndex = useCallback(
    // objectName: ohg | frame, newValue: "0", "1", ...
    (
      currentSelectedIndex: SelectedIndexType,
      objectName: keyof SelectedIndexType,
      newValue: string,
    ) => {
      // 화면상의 select 컴포넌트 업데이트
      const newIndex = Number(newValue);
      const newSelectedIndex = {
        ...currentSelectedIndex,
        [objectName]: newIndex,
      };
      setSelectedIndex(newSelectedIndex);

      // 유니티 스크립트 호출 - objectName 및 함수 이름은 유니티의 것과 동일해야 함
      UNSAFE__unityInstance?.SendMessage(objectName, "HandleSelect", newIndex);

      handleMatchUpdate(newSelectedIndex)
        // 매치율 이용하여 컴포넌트 업데이트
        .then((match) => {
          //
        })
        .catch((err) => {
          // 에러처리
        });
    },
    [UNSAFE__unityInstance, handleMatchUpdate],
  );

  return (
    <>
      <div className="mb-5 mt-5">
        새 Unity 프로젝트를 생성하고, WebGL로 빌드 후 빌드 산출물을
        react-unity-webgl 라이브러리를 통해 실행했다.
      </div>
      {option?.[Number(p)] && (
        <div className="mb-5">{option[Number(p)].description}</div>
      )}
      <div className="flex h-[650px] w-[800px] flex-col">
        {isLoaded === false && (
          <div className="absolute z-10 flex h-[600px] w-[800px] items-center justify-center bg-gray-500">
            <p>Loading... ({loadingPercentage}%)</p>
          </div>
        )}
        <Unity className="h-[600px] w-[800px]" unityProvider={unityProvider} />
        <div className="mt-auto flex">
          <select
            value={Number(p)}
            onChange={(e) => (location.href = `/unity?p=${e.target.value}`)}
            className="mt-5"
          >
            {option.map((o, i) => (
              <option key={`${o}-${i}`} value={i}>
                {o.name}
              </option>
            ))}
          </select>
          {Number(p) == 0 && (
            <>
              <select
                value={selectedIndex.ohg}
                onChange={(e) =>
                  handleSelectIndex(selectedIndex, "ohg", e.target.value)
                }
                className="ml-5 mt-5"
              >
                {ohg?.map((o, i) => (
                  <option key={`${o.label}-${i}`} value={o.value}>
                    {o.label}
                  </option>
                ))}
              </select>
              <select
                value={selectedIndex.frame}
                onChange={(e) =>
                  handleSelectIndex(selectedIndex, "frame", e.target.value)
                }
                className="ml-5 mt-5"
              >
                {frame.map((o, i) => (
                  <option key={`${o.label}-${i}`} value={o.value}>
                    {o.label}
                  </option>
                ))}
              </select>
              <div className="ml-5 mt-5">
                매치율: {`${match?.toFixed?.(2) ?? 100}`}%
              </div>
            </>
          )}
          <Image
            src={"/unity/3d-test/TemplateData/fullscreen-button.png"}
            alt="전체 화면 버튼"
            title="전체 화면으로 보기"
            width={38}
            height={38}
            className="ml-auto mt-2 cursor-pointer"
            onClick={() => UNSAFE__unityInstance?.SetFullscreen(1)}
          />
        </div>
      </div>
    </>
  );
}
