"use client";

import type { TocItem } from "@/components/lab-remark/extract-toc";
import { useLabContext } from "@/components/labs/context";
import DeployLabForm, {
  type DeployLabFormData,
} from "@/components/labs/deploy-lab-form";
import { useLabClusterRegions } from "@/components/labs/hook";
import {
  type LabMetaV2,
  type TiDBEnvironment,
  useLabMeta,
  useLabParts,
} from "@/components/labs/hooks-v2";
import { LabContentPlaceholder } from "@/components/labs/lab-content-placeholder";
import LabExternalMaterials from "@/components/labs/lab-external-materials";
import LabFooter from "@/components/labs/lab-footer";
import { LabInstanceContext } from "@/components/labs/lab-instance-context";
import { LabLayoutV3 } from "@/components/labs/lab-layout-v3";
import { LabNavV2 } from "@/components/labs/lab-nav";
import { LabScreenAlert } from "@/components/labs/lab-screen-alert";
import { parseSectionsV2 } from "@/components/labs/parse-section";
import Markdown from "@/components/markdown/markdown";
import { useLocale, useLocaleFunction } from "@/hooks/use-localed";
import { type LabMetaExtra } from "@/lib/api/labs";
import {
  type ClusterRegionKey,
  toClusterRegionInfo,
} from "@/lib/cluster-regions";
import { matchParent } from "@/lib/dom";
import { useRouter, useSearchParams } from "next/navigation";
import {
  type ReactElement,
  type SetStateAction,
  useEffect,
  useMemo,
  useRef,
  useState,
  useTransition,
} from "react";

export default function LabPreviewV2({
  lab: propLab,
  region,
  serverlessGrantId,
}: {
  lab: LabMetaV2 & LabMetaExtra;
  region?: ClusterRegionKey;
  serverlessGrantId?: number;
}) {
  const locale = useLocale();
  const { data: lab = propLab } = useLabMeta(propLab.lab_code, propLab);

  const router = useRouter();
  const searchParams = useSearchParams();
  const step = parseInt(searchParams.get("step") ?? "0");
  const [navigating, startNavigation] = useTransition();

  const onStepChange = (value: SetStateAction<number>) => {
    let nextStep: number;
    if (typeof value === "function") {
      nextStep = value(step);
    } else {
      nextStep = value;
    }
    startNavigation(() => {
      if (nextStep) {
        router.push(`/lab?preview=${lab.lab_code}&step=${nextStep}`);
      } else {
        router.push(`/lab?preview=${lab.lab_code}`);
      }
    });
  };

  const parts = useLabParts(lab.lab_code);
  const { data: clusterRegions } = useLabClusterRegions();

  const [formData, setFormData] = useState<DeployLabFormData | undefined>();

  const [tidbEnvironment, setTidbEnvironment] = useState<TiDBEnvironment>(
    lab.tidb_environments[0]
  );

  const { parsedSections, env } = useMemo(() => {
    const regionInfo = formData?.region
      ? toClusterRegionInfo(formData.region)
      : null;
    const regionInfoData =
      regionInfo && clusterRegions
        ? clusterRegions[regionInfo.cloud_provider][regionInfo.region_name]
        : null;

    const env = {
      TIDB_VERSION: formData?.tidb_version ?? null,
      CLOUD_PROVIDER: regionInfo?.cloud_provider ?? null,
      REGION_CODE: regionInfoData?.["region-code"] ?? null,
      REGION_NAME: regionInfoData?.["region-name"] ?? null,
      TIDB_ENVIRONMENT: tidbEnvironment,
    };

    const parsedSections = parseSectionsV2(
      locale,
      parts?.data ?? [],
      env,
      true,
      true
    );

    return { parsedSections, env };
  }, [
    parts.data,
    locale,
    formData?.tidb_version,
    formData?.region,
    clusterRegions,
    tidbEnvironment,
  ]);

  return (
    <LabInstanceContext
      value={{
        lab: {
          lab_code: lab.lab_code,
        } as never,
        meta: lab,
        environmentVariables: env,
        error: undefined,
        isReady: false,
        resources: undefined,
        parsedSections,
        navigating,
        step,
        onStepChange,
        resourcesDialogOpen: false,
        onResourcesDialogOpenChanged: () => {},
      }}
    >
      <LabLayoutV3
        side={
          <>
            <DeployLabForm
              lab={lab}
              serverlessGrantId={serverlessGrantId}
              region={region}
              onChange={setFormData}
              tidbEnvironment={tidbEnvironment}
              onTiDBEnvironmentChange={setTidbEnvironment}
            />
            <LabExternalMaterials className="-mt-4" lab={lab} />
          </>
        }
        main={<LabPreviewMain lab={lab} sections={parsedSections} />}
        nav={<LabNavV2 preview />}
        mainFooter={<LabFooter />}
      ></LabLayoutV3>
    </LabInstanceContext>
  );
}

type ParsedSection = {
  title: string;
  element: ReactElement;
  toc: TocItem[];
};

function LabPreviewMain({
  lab,
  sections,
}: {
  lab?: LabMetaV2;
  sections: ParsedSection[];
}) {
  const { step } = useLabContext();
  const t = useLocaleFunction();

  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const main = ref.current;
    if (main) {
      const viewport = matchParent(main, "[data-radix-scroll-area-viewport]");
      if (viewport) {
        viewport.scrollTo({
          top: 0,
        });
      }
    }
  }, [step]);

  return (
    <main className="w-lab-main p-4 relative" ref={ref}>
      <LabScreenAlert />
      <Markdown className="p-4 relative" enableAIExplain={false}>
        <h1 className="md:hidden" aria-hidden>
          {t(lab, "title")}
        </h1>
        {sections[step]?.element ?? <LabContentPlaceholder />}
      </Markdown>
    </main>
  );
}
