import { URLS } from '@akinon/next/data/urls';
import { Metadata, AsyncPageProps } from '@akinon/next/types';
import logger from '@akinon/next/utils/log';
import { notFound } from 'next/navigation';

type PrettyUrlResult = {
  matched: boolean;
  path?: string;
  pk?: number;
};

const resolvePrettyUrlHandler =
  (pathname: string, ip: string | null) => async () => {
    let results = [] as { old_path: string }[];
    let prettyUrlResult: PrettyUrlResult = {
      matched: false
    };

    try {
      const requestUrl = URLS.misc.prettyUrls(`/${pathname}/`);

      logger.debug(`Resolving pretty url`, { pathname, requestUrl, ip });

      const start = Date.now();
      const apiResponse = await fetch(requestUrl, {
        next: {
          revalidate: 0
        }
      });
      const data = await apiResponse.json();
      ({ results } = data);
      const end = Date.now();
      console.warn('Pretty url response time', end - start, requestUrl);

      const matched = results.length > 0;
      const [{ old_path: path } = { old_path: '' }] = results;
      let pk;

      if (matched) {
        const pkRegex = /\/(\d+)\/$/;
        const match = path.match(pkRegex);
        pk = match ? parseInt(match[1]) : undefined;
      }

      prettyUrlResult = {
        matched,
        path,
        pk
      };

      logger.trace('Pretty url result', { prettyUrlResult, ip });
    } catch (error) {
      logger.error('Error resolving pretty url', { error, pathname, ip });
    }

    return prettyUrlResult;
  };

export async function generateMetadata(props: AsyncPageProps) {
  const params = await props.params;
  let result: Metadata = {};
  const { prettyurl } = params;
  const pageSlug = prettyurl
    .filter((x) => !x.startsWith('searchparams'))
    .join('/');

  const searchParams = new URLSearchParams(
    decodeURIComponent(
      prettyurl
        .find((x) => x.startsWith('searchparams'))
        ?.replace('searchparams%7C', '')
    ) ?? {}
  );
  const prettyUrlResult = await resolvePrettyUrlHandler(pageSlug, null)();

  if (!prettyUrlResult.matched) {
    return notFound();
  }

  const commonProps = {
    params: Promise.resolve({
      ...params,
      pk: prettyUrlResult.pk
    }),
    searchParams: Promise.resolve(searchParams)
  };

  try {
    if (prettyUrlResult.path.startsWith('/product/')) {
      await import('@product/[pk]/page').then(async (module) => {
        result = await module['generateMetadata']?.(commonProps as any);
      });
    }

    if (prettyUrlResult.path.startsWith('/group-product/')) {
      await import('@group-product/[pk]/page').then(async (module) => {
        result = await module['generateMetadata']?.(commonProps as any);
      });
    }

    if (prettyUrlResult.path.startsWith('/category/')) {
      await import('@category/[pk]/page').then(async (module) => {
        result = await module['generateMetadata']?.(commonProps as any);
      });
    }

    if (prettyUrlResult.path.startsWith('/special-page/')) {
      await import('@special-page/[pk]/page').then(async (module) => {
        result = await module['generateMetadata']?.(commonProps as any);
      });
    }

    if (prettyUrlResult.path.startsWith('/flat-page/')) {
      await import('@flat-page/[pk]/page').then(async (module) => {
        result = await module['generateMetadata']?.(commonProps as any);
      });
    }
    // eslint-disable-next-line no-empty
  } catch (error) {}

  return result;
}

export const dynamic = 'force-static';
export const revalidate = 300;

export default async function Page(props) {
  const params = await props.params;
  const { prettyurl } = params;
  const pageSlug = prettyurl
    .filter((x) => !x.startsWith('searchparams'))
    .join('/');

  const urlSearchParams = new URLSearchParams(
    decodeURIComponent(
      prettyurl
        .find((x) => x.startsWith('searchparams'))
        ?.replace('searchparams%7C', '')
    ) ?? {}
  );

  const searchParams = {};

  for (const [key, value] of urlSearchParams.entries() as unknown as Array<
    [string, string]
  >) {
    if (!searchParams[key]) {
      searchParams[key] = [];
    }
    searchParams[key].push(value);
  }

  const result = await resolvePrettyUrlHandler(pageSlug, null)();

  if (!result.matched) {
    return notFound();
  }

  const commonProps = {
    params: {
      ...params,
      pk: result.pk
    },
    searchParams: urlSearchParams
  } as any;

  if (result.path.startsWith('/category/')) {
    const CategoryPage = (await import('@category/[pk]/page')).default;
    return <CategoryPage {...commonProps} />;
  }

  if (result.path.startsWith('/product/')) {
    const ProductPage = (await import('@product/[pk]/page')).default;
    return <ProductPage {...commonProps} />;
  }

  if (result.path.startsWith('/group-product/')) {
    const GroupProduct = (await import('@group-product/[pk]/page')).default;
    return <GroupProduct {...commonProps} />;
  }

  if (result.path.startsWith('/special-page/')) {
    const SpecialPage = (await import('@special-page/[pk]/page')).default;
    return <SpecialPage {...commonProps} />;
  }

  if (result.path.startsWith('/flat-page/')) {
    const FlatPage = (await import('@flat-page/[pk]/page')).default;
    return <FlatPage {...commonProps} />;
  }

  return null;
}
