import { FullPageEmptyState } from '@/components/full-page-empty-state';
import { OverviewFilterButton } from '@/components/overview/filters/overview-filters-buttons';
import { OverviewInterval } from '@/components/overview/overview-interval';
import { OverviewRange } from '@/components/overview/overview-range';
import { useOverviewOptions } from '@/components/overview/useOverviewOptions';
import { PageContainer } from '@/components/page-container';
import { PageHeader } from '@/components/page-header';
import { Pagination } from '@/components/pagination';
import { FloatingPagination } from '@/components/pagination-floating';
import { ReportChart } from '@/components/report-chart';
import { Skeleton } from '@/components/skeleton';
import { Input } from '@/components/ui/input';
import { TableButtons } from '@/components/ui/table';
import { useAppContext } from '@/hooks/use-app-context';
import { useEventQueryFilters } from '@/hooks/use-event-query-filters';
import { useNumber } from '@/hooks/use-numer-formatter';
import { useSearchQueryState } from '@/hooks/use-search-query-state';
import { useTRPC } from '@/integrations/trpc/react';
import type { RouterOutputs } from '@/trpc/client';
import { PAGE_TITLES, createProjectTitle } from '@/utils/title';
import type { IChartRange, IInterval } from '@openpanel/validation';
import { keepPreviousData, useQuery } from '@tanstack/react-query';
import { createFileRoute } from '@tanstack/react-router';
import { parseAsInteger, useQueryState } from 'nuqs';
import { memo } from 'react';

export const Route = createFileRoute('/_app/$organizationId/$projectId/pages')({
  component: Component,
  head: () => {
    return {
      meta: [
        {
          title: createProjectTitle(PAGE_TITLES.PAGES),
        },
      ],
    };
  },
});

function Component() {
  const { projectId } = Route.useParams();
  const trpc = useTRPC();
  const take = 20;
  const { range, interval } = useOverviewOptions();
  const [filters] = useEventQueryFilters();
  const [cursor, setCursor] = useQueryState(
    'cursor',
    parseAsInteger.withDefault(1),
  );

  const { debouncedSearch, setSearch, search } = useSearchQueryState();
  const query = useQuery(
    trpc.event.pages.queryOptions(
      {
        projectId,
        cursor,
        take,
        search: debouncedSearch,
        range,
        interval,
        filters,
      },
      {
        placeholderData: keepPreviousData,
      },
    ),
  );
  const data = query.data ?? [];

  return (
    <PageContainer>
      <PageHeader
        title="Pages"
        description="Access all your pages here"
        className="mb-8"
      />
      <TableButtons>
        <OverviewRange />
        <OverviewInterval />
        <OverviewFilterButton enableEventsFilter />
        <Input
          className="self-auto"
          placeholder="Search path"
          value={search ?? ''}
          onChange={(e) => {
            setSearch(e.target.value);
            setCursor(0);
          }}
        />
      </TableButtons>
      {data.length === 0 && !query.isLoading && (
        <FullPageEmptyState
          title="No pages"
          description={'Integrate our web sdk to your site to get pages here.'}
        />
      )}
      {query.isLoading && (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <PageCardSkeleton />
          <PageCardSkeleton />
          <PageCardSkeleton />
        </div>
      )}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        {data.map((page) => {
          return (
            <PageCard
              key={page.path}
              page={page}
              range={range}
              interval={interval}
              projectId={projectId}
            />
          );
        })}
      </div>
      {data.length !== 0 && (
        <div className="p-4">
          <FloatingPagination
            firstPage={cursor > 1 ? () => setCursor(1) : undefined}
            canNextPage={true}
            canPreviousPage={cursor > 0}
            pageIndex={cursor - 1}
            nextPage={() => {
              setCursor((p) => p + 1);
            }}
            previousPage={() => {
              setCursor((p) => p - 1);
            }}
          />
        </div>
      )}
    </PageContainer>
  );
}

const PageCard = memo(
  ({
    page,
    range,
    interval,
    projectId,
  }: {
    page: RouterOutputs['event']['pages'][number];
    range: IChartRange;
    interval: IInterval;
    projectId: string;
  }) => {
    const number = useNumber();
    const { apiUrl } = useAppContext();
    return (
      <div className="card">
        <div className="row gap-4 justify-between p-4 py-2 items-center">
          <div className="row gap-2 items-center h-16">
            <img
              src={`${apiUrl}/misc/og?url=${page.origin}${page.path}`}
              alt={page.title}
              className="size-10 rounded-sm object-cover"
              loading="lazy"
              decoding="async"
            />
            <div className="col min-w-0">
              <div className="font-medium leading-[28px] truncate">
                {page.title}
              </div>
              <a
                target="_blank"
                rel="noreferrer"
                href={`${page.origin}${page.path}`}
                className="text-muted-foreground font-mono truncate hover:underline"
              >
                {page.path}
              </a>
            </div>
          </div>
        </div>
        <div className="row border-y">
          <div className="center-center col flex-1 p-4 py-2">
            <div className="font-medium text-xl font-mono">
              {number.formatWithUnit(page.avg_duration, 'min')}
            </div>
            <div className="text-muted-foreground whitespace-nowrap text-sm">
              duration
            </div>
          </div>
          <div className="center-center col flex-1 p-4 py-2">
            <div className="font-medium text-xl font-mono">
              {number.formatWithUnit(page.bounce_rate / 100, '%')}
            </div>
            <div className="text-muted-foreground whitespace-nowrap text-sm">
              bounce rate
            </div>
          </div>
          <div className="center-center col flex-1 p-4 py-2">
            <div className="font-medium text-xl font-mono">
              {number.format(page.sessions)}
            </div>
            <div className="text-muted-foreground whitespace-nowrap text-sm">
              sessions
            </div>
          </div>
        </div>
        <ReportChart
          options={{
            hideID: true,
            hideXAxis: true,
            hideYAxis: true,
            aspectRatio: 0.15,
          }}
          report={{
            lineType: 'linear',
            breakdowns: [],
            name: 'screen_view',
            metric: 'sum',
            range,
            interval,
            previous: true,

            chartType: 'linear',
            projectId,
            series: [
              {
                type: 'event',
                id: 'A',
                name: 'screen_view',
                segment: 'event',
                filters: [
                  {
                    id: 'path',
                    name: 'path',
                    value: [page.path],
                    operator: 'is',
                  },
                  {
                    id: 'origin',
                    name: 'origin',
                    value: [page.origin],
                    operator: 'is',
                  },
                ],
              },
            ],
          }}
        />
      </div>
    );
  },
);

const PageCardSkeleton = memo(() => {
  return (
    <div className="card">
      <div className="row gap-4 justify-between p-4 py-2 items-center">
        <div className="row gap-2 items-center h-16">
          <Skeleton className="size-10 rounded-sm" />
          <div className="col min-w-0">
            <Skeleton className="h-3 w-32 mb-2" />
            <Skeleton className="h-3 w-24" />
          </div>
        </div>
      </div>
      <div className="row border-y">
        <div className="center-center col flex-1 p-4 py-2">
          <Skeleton className="h-6 w-16 mb-1" />
          <Skeleton className="h-4 w-12" />
        </div>
        <div className="center-center col flex-1 p-4 py-2">
          <Skeleton className="h-6 w-12 mb-1" />
          <Skeleton className="h-4 w-16" />
        </div>
        <div className="center-center col flex-1 p-4 py-2">
          <Skeleton className="h-6 w-14 mb-1" />
          <Skeleton className="h-4 w-14" />
        </div>
      </div>
      <div className="p-4">
        <Skeleton className="h-16 w-full rounded" />
      </div>
    </div>
  );
});
