import { useEffect, useState, useMemo } from 'react';
import { useToast } from '../../hooks/use-toast';
import { getUrlParams } from '../../lib/browser';
import { httpGet } from '../../lib/http';
import type { ResourceType } from '../../lib/resource-progress';
import type { AllowedActivityActionType } from '../Activity/ActivityStream';
import { pageProgressMessage } from '../../stores/page';
import { TeamActivityItem } from './TeamActivityItem';
import { TeamActivityTopicsModal } from './TeamActivityTopicsModal';
import { TeamEmptyStream } from './TeamEmptyStream';
import { Pagination } from '../Pagination/Pagination';

export type TeamStreamActivity = {
  _id?: string;
  resourceType: ResourceType | 'question';
  resourceId: string;
  resourceTitle: string;
  resourceSlug?: string;
  isCustomResource?: boolean;
  actionType: AllowedActivityActionType;
  topicTitles?: string[];
  createdAt: Date;
  updatedAt: Date;
};

export interface TeamActivityStreamDocument {
  _id?: string;
  teamId: string;
  userId: string;
  activity: TeamStreamActivity[];
  createdAt: Date;
  updatedAt: Date;
}

type GetTeamActivityResponse = {
  data: {
    users: {
      _id: string;
      name: string;
      avatar?: string;
      username?: string;
      memberId?: string;
    }[];
    activities: TeamActivityStreamDocument[];
  };
  totalCount: number;
  totalPages: number;
  currPage: number;
  perPage: number;
};

type TeamActivityPageProps = {
  teamId?: string;
};

export function TeamActivityPage(props: TeamActivityPageProps) {
  const { teamId: defaultTeamId } = props;
  const { t: teamId = defaultTeamId } = getUrlParams();

  const toast = useToast();

  const [isLoading, setIsLoading] = useState(true);
  const [selectedActivity, setSelectedActivity] =
    useState<TeamStreamActivity | null>(null);
  const [teamActivities, setTeamActivities] = useState<GetTeamActivityResponse>(
    {
      data: {
        users: [],
        activities: [],
      },
      totalCount: 0,
      totalPages: 0,
      currPage: 1,
      perPage: 21,
    },
  );
  const [currPage, setCurrPage] = useState(1);

  const getTeamProgress = async (currPage: number = 1) => {
    const { response, error } = await httpGet<GetTeamActivityResponse>(
      `${import.meta.env.PUBLIC_API_URL}/v1-get-team-activity/${teamId}`,
      {
        currPage,
      },
    );
    if (error || !response) {
      toast.error(error?.message || 'Failed to get team activity');
      return;
    }

    setTeamActivities(response);
    setCurrPage(response.currPage);
  };

  useEffect(() => {
    if (!teamId) {
      return;
    }

    setIsLoading(true);
    setTeamActivities({
      data: {
        users: [],
        activities: [],
      },
      totalCount: 0,
      totalPages: 0,
      currPage: 1,
      perPage: 21,
    });
    setCurrPage(1);
    getTeamProgress().then(() => {
      pageProgressMessage.set('');
      setIsLoading(false);
    });
  }, [teamId]);

  const { users, activities } = teamActivities?.data;
  const validActivities = useMemo(() => {
    return activities?.filter((activity) => {
      return (
        activity.activity.length > 0 &&
        activity.activity.some((t) => (t?.topicTitles?.length || 0) > 0)
      );
    });
  }, [activities]);

  const sortedUniqueCreatedAt = useMemo(() => {
    return new Set(
      validActivities
        ?.map((activity) => new Date(activity.createdAt).setHours(0, 0, 0, 0))
        .sort((a, b) => {
          return new Date(b).getTime() - new Date(a).getTime();
        }),
    );
  }, [validActivities]);

  const usersWithActivities = useMemo(() => {
    const enrichedUsers: {
      _id: string;
      name: string;
      avatar?: string;
      username?: string;
      activities: TeamStreamActivity[];
    }[] = [];

    for (const uniqueCreatedAt of sortedUniqueCreatedAt) {
      const uniqueActivities = validActivities.filter(
        (activity) =>
          new Date(activity.createdAt).setHours(0, 0, 0, 0) === uniqueCreatedAt,
      );

      const usersWithUniqueActivities = users
        .map((user) => {
          const userActivities = uniqueActivities
            .filter((activity) => activity.userId === user._id)
            .flatMap((activity) => activity.activity)
            .filter((activity) => (activity?.topicTitles?.length || 0) > 0)
            .sort((a, b) => {
              return (
                new Date(b.updatedAt).getTime() -
                new Date(a.updatedAt).getTime()
              );
            });

          return {
            ...user,
            activities: userActivities,
          };
        })
        .filter((user) => user.activities.length > 0)
        .sort((a, b) => {
          return (
            new Date(b.activities[0].updatedAt).getTime() -
            new Date(a.activities[0].updatedAt).getTime()
          );
        });

      enrichedUsers.push(...usersWithUniqueActivities);
    }

    return enrichedUsers;
  }, [users, activities]);

  if (!teamId) {
    window.location.href = '/';
    return;
  }

  if (isLoading) {
    return null;
  }

  return (
    <>
      {selectedActivity && (
        <TeamActivityTopicsModal
          activity={selectedActivity}
          onClose={() => setSelectedActivity(null)}
        />
      )}

      {usersWithActivities.length > 0 ? (
        <>
          <h3 className="mb-4 flex w-full items-center justify-between text-xs uppercase text-gray-400">
            Team Activity
          </h3>
          <ul className="mb-4 mt-2 flex flex-col gap-3">
            {usersWithActivities.map((user, index) => {
              return (
                <TeamActivityItem
                  key={`${user._id}-${index}`}
                  user={user}
                  teamId={teamId}
                  onTopicClick={setSelectedActivity}
                />
              );
            })}
          </ul>

          <Pagination
            currPage={currPage}
            totalPages={teamActivities.totalPages}
            totalCount={teamActivities.totalCount}
            perPage={teamActivities.perPage}
            onPageChange={(page) => {
              setCurrPage(page);
              pageProgressMessage.set('Loading...');
              getTeamProgress(page).finally(() => {
                pageProgressMessage.set('');
              });
            }}
          />
        </>
      ) : (
        <TeamEmptyStream teamId={teamId} />
      )}
    </>
  );
}