import { Metadata } from "next";
import { redirect } from "next/navigation";

import ProfileHome from "@/components/pages/participant/profile/tabs/profile-overview";
import { ProfileCollection } from "@/types/profile/profile-update-schema";
import { getProfileData } from "@/services/general-actions";
import { retrieveUserToken } from "@/lib/user-session";
import { INTERNAL_PAGES } from "@/constants/pages-mapping/internal-pages-mapping";

const INTERNAL_CONTACT_KEYS = [
  "city",
  "state",
  "address",
  "alternativeContactNumber",
]; // filter out city, state and address keys because they are for internal usage only and shouldn't impact the calculation of filled fields.

export const metadata: Metadata = {
  title: "Profile area",
  description:
    "Update your participant profile to receive more relevant paid research invitations and keep your account up-to-date.",
  openGraph: {
    title: "Profile area",
    description:
      "Update your participant profile to receive more relevant paid research invitations and keep your account up-to-date.",
    images: [
      {
        url: "/global-assets/pfr-logo-og-participant.svg",
        alt: "People for Research logo, featuring a person inside a circle, representing a focus on human-centered research and activities.",
        width: 200,
        height: 150,
      },
    ],
  },
  twitter: {
    card: "summary_large_image",
    title: "Profile area",
    images: "/global-assets/pfr-logo-og-participant.svg",
    description:
      "Update your participant profile to receive more relevant paid research invitations and keep your account up-to-date.",
  },
};

export default async function ProfilePage({
  searchParams,
}: {
  searchParams: { email?: string };
}) {
  const { email } = searchParams;
  const userToken = await retrieveUserToken();

  if (!userToken) {
    const target = email
      ? `${INTERNAL_PAGES.participant.login}?email=${encodeURIComponent(email)}`
      : INTERNAL_PAGES.participant.login;

    redirect(target);
  }

  const participantData = await getProfileData(userToken);
  const participantFirstName = participantData.participant.firstName;
  const memberSince = participantData.personalInformation.signUpDate;

  const getFilledFields = (obj: any): string[] => {
    return Object.keys(obj).filter((key) => {
      const value = obj[key];
      return (
        value !== undefined &&
        value !== null &&
        value !== "" &&
        value !== 0 &&
        !(Array.isArray(value) && value.length === 0)
      );
    });
  };

  const calculatePercentageBySection = (
    filledFields: string[],
    section: string[],
  ): number => {
    return Math.round(
      (filledFields.filter((field) => section.includes(field)).length /
        section.length) *
        100,
    );
  };

  const getUserSeniorityLevel = (financialEmployment: any): boolean => {
    // values: mid-level, senior-level, manager, head of dept and company director/CEO
    const seniorityValues = [2, 3, 4, 5, 6];

    return (
      financialEmployment.seniorityLevelIds?.some((seniority: number) =>
        seniorityValues.includes(seniority),
      ) ?? false
    );
  };

  const filterInternalContactKeys = (keys: string[]): string[] => {
    return keys.filter((key) => !INTERNAL_CONTACT_KEYS.includes(key));
  };

  const getCompletionPercentage = (percentagesBySection: {
    [key: string]: number;
  }): number => {
    const sectionCount = Object.keys(percentagesBySection).length;
    const totalPercentage = Object.values(percentagesBySection).reduce(
      (total, percentage) => total + percentage,
      0,
    );

    let completionPercentage = Math.round(totalPercentage / sectionCount);
    return Math.min(completionPercentage, 100);
  };

  const { participant, personalInformation, businessInformation } =
    participantData;

  const profileData: ProfileCollection = {
    personalInformation: {
      firstName: participant.firstName,
      lastName: participant.lastName,
      dateOfBirth: participant.dateOfBirth,
      genderId: personalInformation.genderId,
      ethnicityId: personalInformation.ethnicityId,
      nationalityIds: personalInformation.nationalityIds,
      accessibilitiesIds: personalInformation.accessibilitiesIds,
      techAbilityId: personalInformation.techAbilityId,
      deviceIds: personalInformation.deviceIds,
    },
    companyInformation: {
      companyName: businessInformation.companyName,
      companyTypeId: businessInformation.companyTypeId,
      isDecisionMaker: businessInformation.isDecisionMaker,
      tradeActivitiesIds: businessInformation.tradeActivitiesIds,
      companySizeId: businessInformation.companySizeId,
      isVATRegistered: businessInformation.isVATRegistered,
      companyTurnoverId: businessInformation.companyTurnoverId,
    },
    financialEmployment: {
      financialProductsIds: businessInformation.financialProductsIds,
      seniorityLevelIds: businessInformation.seniorityLevelIds,
      benefitsIds: personalInformation.benefitsIds,
      industryId: businessInformation.industryId,
      employmentStatusIds: businessInformation.employmentStatusIds,
      individualIncomeId: businessInformation.incomeBracketId,
      occupation: businessInformation.occupation,
    },
    life: {
      maritalStatusId: personalInformation.maritalStatusId,
      hasChildren: personalInformation.hasChildren,
      householdIds: personalInformation.householdIds,
      educationLevelId: personalInformation.educationLevelId,
      drivingOptionsIds: personalInformation.drivingOptionsIds,
    },
    contactInformation: {
      email: participant.email,
      countryId: personalInformation.countryId,
      phoneNumber: participant.phoneNumber,
      postCode: personalInformation.postCode,
      alternativeContactNumber: personalInformation.alternativeContactNumber,
      city: personalInformation.city,
      state: personalInformation.state,
      address: personalInformation.formattedAddress,
    },
    settings: {
      isSubscribedPrizeDraws: participant.isSubscribedPrizeDraws,
      isSubscribed: participant.isSubscribed,
    },
  };

  const isUserSeniorProfessional = getUserSeniorityLevel(businessInformation);

  const filledFields = [
    ...getFilledFields(profileData.personalInformation),
    ...getFilledFields(profileData.companyInformation),
    ...getFilledFields(profileData.financialEmployment),
    ...getFilledFields(profileData.life),
    ...getFilledFields(profileData.contactInformation),
  ];

  const percentagesBySection = {
    personalInformation: calculatePercentageBySection(
      filledFields,
      Object.keys(profileData.personalInformation),
    ),
    life: calculatePercentageBySection(
      filledFields,
      Object.keys(profileData.life),
    ),
    financialEmployment: isUserSeniorProfessional
      ? calculatePercentageBySection(
          filledFields,
          Object.keys(profileData.financialEmployment),
        )
      : calculatePercentageBySection(filledFields, [
          "employmentStatusIds",
          "individualIncomeId",
        ]),
    ...(isUserSeniorProfessional && {
      companyInformation: calculatePercentageBySection(
        filledFields,
        Object.keys(profileData.companyInformation),
      ),
    }),
    contactInformation: calculatePercentageBySection(
      filledFields,
      filterInternalContactKeys(Object.keys(profileData.contactInformation)),
    ),
  };

  const completionPercentage = getCompletionPercentage(percentagesBySection);

  return (
    <ProfileHome
      isSeniorProfessional={isUserSeniorProfessional}
      memberSince={memberSince}
      participantFirstName={participantFirstName}
      percentagesBySection={percentagesBySection}
      totalCompletion={completionPercentage}
    />
  );
}
