import React, { useMemo } from 'react';
import {
  CrmConvertLeadModal,
  type CrmConvertLeadAction,
  type CrmConvertLeadApi,
  type CrmConvertLeadHost,
  type CrmConvertLeadLookupProps,
  type CrmConvertLeadObjectMetadata,
  type CrmConvertLeadRecord,
} from './convert-lead-modal';
import {
  CrmCreateRecordFromSourceModal,
  type CrmCreateRecordFromSourceAction,
  type CrmCreateRecordFromSourceApi,
  type CrmCreateRecordFromSourceHost,
} from './create-record-from-source-modal';
import {
  CrmTaskActivityQuickCreateModal,
  type CrmTaskActivityAction,
  type CrmTaskActivityApi,
  type CrmTaskActivityHost,
  type CrmTaskActivityObjectMetadata,
  type CrmTaskActivityRecord,
} from './task-activity-quick-create-modal';
import { CrmConvertedLeadBanner, type CrmConvertedLeadBannerHost } from './converted-lead-banner';
import { crmActivityTimelineSurface } from './activity-timeline-surface';
import {
  CrmSendRecordEmailModal,
  type CrmSendRecordEmailAction,
  type CrmSendRecordEmailApi,
  type CrmSendRecordEmailHost,
  type CrmSendRecordEmailObjectMetadata,
  type CrmSendRecordEmailRecord,
} from './send-record-email-modal';

export interface CrmRuntimeActionRendererProps {
  isOpen: boolean;
  onClose: () => void;
  action: CrmConvertLeadAction & CrmCreateRecordFromSourceAction & CrmTaskActivityAction & CrmSendRecordEmailAction;
  record: CrmConvertLeadRecord & CrmTaskActivityRecord & CrmSendRecordEmailRecord;
  objectMetadata: CrmConvertLeadObjectMetadata & CrmTaskActivityObjectMetadata & CrmSendRecordEmailObjectMetadata;
  host: CrmConvertLeadHost & CrmCreateRecordFromSourceHost & CrmTaskActivityHost & CrmSendRecordEmailHost;
}

export interface CrmRuntimeRecordPanelProps {
  record: Record<string, unknown> | null | undefined;
  host: CrmConvertedLeadBannerHost;
}

export interface CrmRuntimeRendererAdapterOptions {
  convertLeadApi: CrmConvertLeadApi;
  createRecordFromSourceApi: CrmCreateRecordFromSourceApi;
  taskActivityApi: CrmTaskActivityApi;
  sendRecordEmailApi: CrmSendRecordEmailApi;
  lookupComponent: React.ComponentType<CrmConvertLeadLookupProps>;
  useTaskObjectMetadata: (objectApiName: string) => {
    metadata?: CrmTaskActivityObjectMetadata | null;
  };
  useCurrentUserId: () => string | null | undefined;
}

export interface CrmRuntimeRendererAdapters<
  TActionRendererProps extends CrmRuntimeActionRendererProps = CrmRuntimeActionRendererProps,
  TRecordPanelProps extends CrmRuntimeRecordPanelProps = CrmRuntimeRecordPanelProps,
> {
  ConvertLeadModal: React.FC<TActionRendererProps>;
  CreateRecordFromSourceModal: React.FC<TActionRendererProps>;
  TaskActivityQuickCreateModal: React.FC<TActionRendererProps>;
  SendRecordEmailModal: React.FC<TActionRendererProps>;
  ConvertedLeadBanner: React.FC<TRecordPanelProps>;
}

export function createCrmRuntimeRendererAdapters<
  TActionRendererProps extends CrmRuntimeActionRendererProps = CrmRuntimeActionRendererProps,
  TRecordPanelProps extends CrmRuntimeRecordPanelProps = CrmRuntimeRecordPanelProps,
>({
  convertLeadApi,
  createRecordFromSourceApi,
  taskActivityApi,
  sendRecordEmailApi,
  lookupComponent,
  useTaskObjectMetadata,
  useCurrentUserId,
}: CrmRuntimeRendererAdapterOptions): CrmRuntimeRendererAdapters<TActionRendererProps, TRecordPanelProps> {
  const ConvertLeadModalAdapter: React.FC<TActionRendererProps> = ({
    isOpen,
    onClose,
    record,
    objectMetadata,
    action,
    host,
  }) => (
    <CrmConvertLeadModal
      isOpen={isOpen}
      onClose={onClose}
      record={record}
      objectMetadata={objectMetadata}
      action={action}
      host={host}
      api={convertLeadApi}
      lookupComponent={lookupComponent}
    />
  );

  const CreateRecordFromSourceModalAdapter: React.FC<TActionRendererProps> = ({
    isOpen,
    onClose,
    action,
    record,
    host,
  }) => (
    <CrmCreateRecordFromSourceModal
      isOpen={isOpen}
      onClose={onClose}
      action={action}
      record={record}
      host={host}
      api={createRecordFromSourceApi}
    />
  );

  const TaskActivityQuickCreateModalAdapter: React.FC<TActionRendererProps> = ({
    isOpen,
    onClose,
    action,
    record,
    objectMetadata,
    host,
  }) => {
    const { metadata: taskMetadata } = useTaskObjectMetadata(
      crmActivityTimelineSurface.quickCreate.targetObjectApiName,
    );
    const currentUserId = useCurrentUserId();
    const rendererMetadata = useMemo(() => ({
      name: objectMetadata.name,
      fields: taskMetadata?.fields ?? [],
    }), [objectMetadata.name, taskMetadata?.fields]);

    return (
      <CrmTaskActivityQuickCreateModal
        isOpen={isOpen}
        onClose={onClose}
        action={action}
        record={record}
        objectMetadata={rendererMetadata}
        host={host}
        api={taskActivityApi}
        currentUserId={currentUserId}
      />
    );
  };

  const SendRecordEmailModalAdapter: React.FC<TActionRendererProps> = ({
    isOpen,
    onClose,
    action,
    record,
    objectMetadata,
    host,
  }) => (
    <CrmSendRecordEmailModal
      isOpen={isOpen}
      onClose={onClose}
      action={action}
      record={record}
      objectMetadata={objectMetadata}
      host={host}
      api={sendRecordEmailApi}
    />
  );

  const ConvertedLeadBannerAdapter: React.FC<TRecordPanelProps> = ({
    record,
    host,
  }) => <CrmConvertedLeadBanner record={record} host={host} />;

  return {
    ConvertLeadModal: ConvertLeadModalAdapter,
    CreateRecordFromSourceModal: CreateRecordFromSourceModalAdapter,
    TaskActivityQuickCreateModal: TaskActivityQuickCreateModalAdapter,
    SendRecordEmailModal: SendRecordEmailModalAdapter,
    ConvertedLeadBanner: ConvertedLeadBannerAdapter,
  };
}
