import BreadCrumbLink from "@/layouts/shared/page.breadcrumbLink";
import {
  getAllCampaignsForAccessList,
  getAllKnownPromoCodes,
  getCampaignPromoCodeMap,
  getUserAccessList,
} from "@/lib/features/access-list/query";
import type {
  AccessListCampaign,
  CampaignPromoCodeMapRow,
  KnownPromoCode,
} from "@/lib/features/access-list/query";
import { updateUserAccessList } from "@/lib/features/access-list/action";
import type { UpdateUserAccessListPayload, UserAccessList } from "@/lib/features/access-list/types";
import { createRoleProtectedLoader } from "@/lib/features/protectedFetcher";
import type { AccessScope, CoreResponse } from "@/lib/features/types";
import { FEATURE_SLUGS, getCheckedAccess } from "@/lib/role-helpers";
import type { Route } from "./+types/page";
import AccessListDetailClientPage from "./_client";

export const handle = {
  breadcrumb: () => (
    <BreadCrumbLink
      links={[{ label: "Access List", to: "/admin/access-list" }, { label: "Edit" }]}
    />
  ),
};

export async function action({ request, params }: Route.ActionArgs) {
  const { userId } = params as { userId: string };
  const { intent, ...payload } = (await request.json()) as {
    intent: string;
  } & UpdateUserAccessListPayload;
  switch (intent) {
    case "update-user-access-list":
      return await updateUserAccessList(userId, payload, request);
    default:
      throw Error("Invalid intent");
  }
}

export const loader = createRoleProtectedLoader(
  FEATURE_SLUGS.promocodeAccessList,
  "read",
  async ({ request, params }) => {
    const { userId } = params as { userId: string };
    const headers = { Cookie: request.headers.get("Cookie") ?? "" };
    const [promoCodesRes, campaignsRes, campaignPromoCodeMapRes, accessRes] = await Promise.all([
      getAllKnownPromoCodes(headers),
      getAllCampaignsForAccessList(headers),
      getCampaignPromoCodeMap(headers),
      getUserAccessList(userId, request),
    ]);
    const accessScope = getCheckedAccess(request, FEATURE_SLUGS.promocodeAccessList);
    return { promoCodesRes, campaignsRes, campaignPromoCodeMapRes, accessRes, accessScope };
  },
);

const AccessListDetailPage: React.FC<Route.ComponentProps> = ({ loaderData }) => {
  const { promoCodesRes, campaignsRes, campaignPromoCodeMapRes, accessRes, accessScope } =
    loaderData as unknown as {
      promoCodesRes: CoreResponse<KnownPromoCode[]>;
      campaignsRes: CoreResponse<AccessListCampaign[]>;
      campaignPromoCodeMapRes: CoreResponse<CampaignPromoCodeMapRow[]>;
      accessRes: CoreResponse<UserAccessList>;
      accessScope: AccessScope;
    };

  return (
    <AccessListDetailClientPage
      key={accessRes?.data?.user?.id}
      user={accessRes?.data?.user ?? undefined}
      promoCodes={promoCodesRes?.data ?? []}
      campaigns={campaignsRes?.data ?? []}
      campaignPromoCodeMap={campaignPromoCodeMapRes?.data ?? []}
      access={
        accessRes?.data ?? {
          user: null,
          promoCodeIds: [],
          campaignIds: [],
          isMember: false,
          canExportCampaigns: true,
          canExportPromoCodes: true,
          canExportMemberReferrals: true,
          canExportReports: true,
        }
      }
      accessScope={accessScope}
    />
  );
};

export default AccessListDetailPage;
