import BreadCrumbLink from "@/layouts/shared/page.breadcrumbLink";
import {
  getMemberByMemberNumber,
  getMemberActivityLogs,
  getMemberSavedSearches,
  getMemberSessionLogs,
  resetMemberPassword,
  syncMemberProfile,
} from "@/lib/features/members/query";
import type {
  CoreMemberActivityLog,
  CoreMemberDetailed,
  CoreMemberSavedSearch,
  CoreMemberSession,
} from "@/lib/features/members/types";
import type { AccessScope, CoreResponse } from "@/lib/features/types";
import { FEATURE_SLUGS, getCheckedAccess } from "@/lib/role-helpers";
import {
  getMyMemberAccess,
  NO_MEMBER_ACCESS,
  type MemberAccess,
} from "@/lib/features/members/access";
import type { Route } from "../../../../layouts/+types/members.layout";
import MemberContactClientPage from "./_client";

export const handle = {
  breadcrumb: ({
    params,
  }: {
    params: { accountId: string; contactId: string };
  }) => (
    <BreadCrumbLink
      links={[
        {
          label: "Accounts",
          to: "/admin/members",
        },
        {
          label: params.accountId,
          to: `/admin/members/${params.accountId}`,
        },
        {
          label: params.contactId,
        },
      ]}
    />
  ),
};

export async function loader({ request, params }: Route.LoaderArgs) {
  const contactId = (params as { contactId: string }).contactId;
  // Promo drilldowns redirect here and pass where to go back to.
  const url = new URL(request.url);
  const fromHref = url.searchParams.get("from") ?? undefined;
  const fromLabel = url.searchParams.get("fromLabel") ?? undefined;
  const accessScope = getCheckedAccess(request, FEATURE_SLUGS.members);
  // Sub-tabs are granted per user in the member module's access record; without
  // the capability the tab is hidden and the call is never made.
  const headers = { Cookie: request.headers.get("Cookie") ?? "" };
  const accessRes = await getMyMemberAccess(headers);
  const memberAccess = accessRes?.success
    ? (accessRes.data as MemberAccess)
    : NO_MEMBER_ACCESS;
  const tabScopes = {
    sessions: memberAccess.can_view_sessions,
    activityLogs: memberAccess.can_view_activity_logs,
    savedSearches: memberAccess.can_view_saved_searches,
  };
  const actionScopes = {
    resetPassword: memberAccess.can_reset_password,
    syncProfile: memberAccess.can_sync_profile,
  };
  const memberResponse = await getMemberByMemberNumber(contactId, headers);
  const member = memberResponse?.data?.member;

  // Console-side activity on this member, same feed the other detail pages use.
  const memberLogsRes =
    member?.member_id && tabScopes.activityLogs
      ? await getMemberActivityLogs(member.member_id, member.user_id, headers)
      : undefined;
  const memberLogs = memberLogsRes?.success
    ? (memberLogsRes.data?.logs ?? [])
    : [];

  // Searches the member saved in the app, straight from the member DB.
  const savedSearchesRes =
    member?.member_id && tabScopes.savedSearches
      ? await getMemberSavedSearches(member.member_id, headers)
      : undefined;
  const savedSearches = savedSearchesRes?.success
    ? (savedSearchesRes.data?.saved_searches ?? [])
    : [];

  if (member?.member_id && tabScopes.sessions) {
    const sessionsResponse = await getMemberSessionLogs(
      member.member_id,
      headers,
    );
    return {
      memberResponse,
      sessionsResponse,
      memberLogs,
      savedSearches,
      accessScope,
      tabScopes,
      actionScopes,
      fromHref,
      fromLabel,
    };
  }
  return {
    memberResponse,
    sessionsResponse: {},
    memberLogs,
    savedSearches,
    accessScope,
    tabScopes,
    actionScopes,
    fromHref,
    fromLabel,
  };
}

export async function action({ request }: Route.LoaderArgs) {
  const headers = { Cookie: request.headers.get("Cookie") ?? "" };
  const { intent, ...payload } = await request.json();
  switch (intent as string) {
    case "reset-member-password":
      const { memberRecordId, ...restPayload } = payload as {
        memberRecordId: string;
        password: string;
      };
      await resetMemberPassword(memberRecordId, restPayload, headers);
      break;
    case "sync-member-profile": {
      const { profileID, ...syncPayload } = payload as {
        profileID: string;
        accountId: string;
        contactId: string;
      };
      return await syncMemberProfile(profileID, syncPayload, headers);
    }
    default:
      break;
  }
}

const MemberContactPage: React.FC<Route.ComponentProps> = ({ loaderData }) => {
  const {
    memberResponse,
    sessionsResponse,
    memberLogs,
    savedSearches,
    accessScope,
    tabScopes,
    actionScopes,
    fromHref,
    fromLabel,
  } = loaderData as unknown as {
    memberResponse: CoreResponse<{
      member: CoreMemberDetailed;
    }>;
    sessionsResponse: CoreResponse<{
      sessions: CoreMemberSession[];
    }>;
    memberLogs: CoreMemberActivityLog[];
    tabScopes?: {
      sessions: boolean;
      activityLogs: boolean;
      savedSearches: boolean;
    };
    actionScopes?: { resetPassword: boolean; syncProfile: boolean };
    fromHref?: string;
    fromLabel?: string;
    savedSearches: CoreMemberSavedSearch[];
    accessScope: AccessScope;
  };
  return (
    <MemberContactClientPage
      member={memberResponse?.data?.member}
      sessions={sessionsResponse?.data?.sessions ?? []}
      memberLogs={memberLogs ?? []}
      savedSearches={savedSearches ?? []}
      tabScopes={tabScopes}
      actionScopes={actionScopes}
      backHref={fromHref}
      backLabel={fromLabel}
      accessScope={accessScope}
    />
  );
};

export default MemberContactPage;
