import type {
    FnCreateImmutableContextForSymbol,
    FnCreateImmutableContextProviderForSymbol,
    ImmutableContext,
} from "@devowl-wp/react-utils";
import { useImmutableContext, useImmutableContextProvider } from "@devowl-wp/react-utils";
import type { ClientBlockerTemplate, ClientServiceTemplate } from "@devowl-wp/service-cloud-consumer";

import type { Card } from "antd";
import type { ComponentProps, ReactNode } from "react";

type TemplateCenterAllowedTypes = ClientServiceTemplate | ClientBlockerTemplate;

type TemplateCenterHeaderQuickLink =
    | {
          id: string;
          onClick: ComponentProps<typeof Card>["onClick"];
          cover: ComponentProps<typeof Card>["cover"];
          title: ReactNode;
          description: ReactNode;
      }
    | "cookie-experts"
    | "service-individual"
    | "blocker-individual"
    | "service-scanner";

type TemplateCenterContextPropsCommon<TemplateType extends TemplateCenterAllowedTypes> = {
    /**
     * Quick links are directly above the cards, e.g. "Create individual service".
     */
    quickLinks: TemplateCenterHeaderQuickLink[];
    /**
     * User wants to download the services from Service Cloud again.
     */
    syncTemplates: () => Promise<void>;
    /**
     * Fetch templates with given filters. Enable `enableLocalFilter` if your callback returns *all* available
     * templates, so a local filter mechanism is applied to the result.
     */
    fetchTemplates: (args: { term: string; isShowOnlyFree: boolean }) => Promise<TemplateType["afterPersist"][]>;
    /**
     * A template got clicked, load the attributes in "use"-ready format.
     */
    fetchUse: (identifier: string, template?: TemplateType["afterPersist"]) => Promise<TemplateType["use"]>;
    /**
     * A template got selected.
     *
     * `template` can be `undefined` if the user clicks on e.g. "Create from scratch".
     */
    onSelect: (template?: TemplateType["use"], initialSelection?: boolean) => void;
    enableLocalFilter: boolean;
    /**
     * When you render the template center within a e.g. React Router page, you can pass
     * URL parameters to automatically select a given template.
     *
     * Can be any template identifier, or `scratch` for an individual template.
     */
    initialSelection: string;
};

const TEMPLATE_CENTER_CONTEXT_SYMBOL = Symbol();
type TemplateCenterContext = ImmutableContext<{
    initialState:
        | Partial<
              {
                  type: "service";
              } & TemplateCenterContextPropsCommon<ClientServiceTemplate>
          >
        | Partial<
              {
                  type: "content-blocker";
              } & TemplateCenterContextPropsCommon<ClientBlockerTemplate>
          >;
}>;

const useTemplateCenter: FnCreateImmutableContextForSymbol<TemplateCenterContext> = () =>
    useImmutableContext<TemplateCenterContext>(TEMPLATE_CENTER_CONTEXT_SYMBOL);

const useTemplateCenterProvider: FnCreateImmutableContextProviderForSymbol<TemplateCenterContext> = (...args) =>
    useImmutableContextProvider<TemplateCenterContext>(TEMPLATE_CENTER_CONTEXT_SYMBOL, ...args);

export {
    type TemplateCenterAllowedTypes,
    type TemplateCenterContextPropsCommon,
    type TemplateCenterHeaderQuickLink,
    type TemplateCenterContext,
    useTemplateCenter,
    useTemplateCenterProvider,
};
