import React, { useEffect, useMemo, useState } from 'react';
import { FilePlus, PackageCheck } from 'lucide-react';
import { BaseModal, Button, useErrorToast, useSuccessToast } from '@nexuscrm/salesforce-crm-standard-frontend/platform/components/ui';
import { CRM_CREATE_FROM_SOURCE_CONFIG_KEYS } from './action-surface-policy';
import {
  buildCrmCreateFromSourcePayload,
  countCrmCreateFromSourcePreviewChildren,
  readCrmCreateFromSourceConfig,
  resolveCrmCreateFromSourceSuccessTarget,
  type CrmCreateFromSourceAction,
  type CrmCreateFromSourcePreviewResult,
  type CrmCreateFromSourceRecord,
} from './create-record-from-source-action';

export interface CrmCreateRecordFromSourceAction extends CrmCreateFromSourceAction {
  label: string;
  endpoint?: string;
  previewEndpoint?: string;
}

export interface CrmCreateRecordFromSourceHost {
  navigateToRecord: (objectApiName: string, recordId: string) => void;
  refreshRecord: () => void;
}

export interface CrmCreateRecordFromSourceApi {
  executeStandardAction: (
    actionEndpoint: string,
    inputs: Record<string, unknown>[],
  ) => Promise<Record<string, unknown>>;
  previewStandardAction: (
    actionPreviewEndpoint: string,
    input: Record<string, unknown>,
  ) => Promise<CrmCreateFromSourcePreviewResult>;
}

export interface CrmCreateRecordFromSourceModalProps {
  isOpen: boolean;
  onClose: () => void;
  action: CrmCreateRecordFromSourceAction;
  record: CrmCreateFromSourceRecord;
  host: CrmCreateRecordFromSourceHost;
  api: CrmCreateRecordFromSourceApi;
}

export const CrmCreateRecordFromSourceModal: React.FC<CrmCreateRecordFromSourceModalProps> = ({
  isOpen,
  onClose,
  action,
  record,
  host,
  api,
}) => {
  const showSuccess = useSuccessToast();
  const showError = useErrorToast();
  const [saving, setSaving] = useState(false);
  const [preview, setPreview] = useState<CrmCreateFromSourcePreviewResult | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);
  const config = readCrmCreateFromSourceConfig(action);

  const payload = useMemo(() => buildCrmCreateFromSourcePayload(action, record), [action, record]);
  const childPreviewObject = config[CRM_CREATE_FROM_SOURCE_CONFIG_KEYS.childPreviewObject];
  const parentPreviewObject = config[CRM_CREATE_FROM_SOURCE_CONFIG_KEYS.parentPreviewObject];
  const successObject = config[CRM_CREATE_FROM_SOURCE_CONFIG_KEYS.successObject];
  const submitLabel = config[CRM_CREATE_FROM_SOURCE_CONFIG_KEYS.submitLabel] || action.label;
  const childCount = countCrmCreateFromSourcePreviewChildren(preview, childPreviewObject);
  const parentObject = parentPreviewObject || preview?.parentPreview?.object || successObject;
  const childObject = childPreviewObject || preview?.childPreview?.[0]?.object;

  useEffect(() => {
    setPreview(null);
    if (!isOpen || !action.previewEndpoint) {
      return;
    }
    let cancelled = false;
    setPreviewLoading(true);
    api.previewStandardAction(action.previewEndpoint, payload)
      .then(result => {
        if (!cancelled) {
          setPreview(result);
        }
      })
      .catch(() => {
        if (!cancelled) {
          setPreview(null);
        }
      })
      .finally(() => {
        if (!cancelled) {
          setPreviewLoading(false);
        }
      });
    return () => {
      cancelled = true;
    };
  }, [action.previewEndpoint, api, isOpen, payload]);

  const handleSubmit = async () => {
    if (!action.endpoint) {
      showError('Error', 'Action endpoint is not declared by action metadata');
      return;
    }

    setSaving(true);
    try {
      const response = await api.executeStandardAction(action.endpoint, [payload]);
      const target = resolveCrmCreateFromSourceSuccessTarget(action, response);
      showSuccess(`${action.label} completed`);
      host.refreshRecord();
      onClose();
      if (target) {
        host.navigateToRecord(target.objectApiName, target.recordId);
      }
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Action execution failed';
      showError('Error', message);
    } finally {
      setSaving(false);
    }
  };

  return (
    <BaseModal
      isOpen={isOpen}
      onClose={onClose}
      title={action.label}
      icon={FilePlus}
      maxWidth="md"
      footer={(
        <div className="flex justify-end gap-3">
          <Button variant="secondary" onClick={onClose} disabled={saving}>
            Cancel
          </Button>
          <Button variant="primary" onClick={handleSubmit} loading={saving}>
            {submitLabel}
          </Button>
        </div>
      )}
    >
      <div className="p-6 space-y-4">
        <div className="rounded-lg border border-gray-200 bg-white p-4">
          <div className="flex items-center gap-3">
            <div className="rounded-lg bg-blue-50 p-2 text-blue-700">
              <FilePlus className="h-5 w-5" />
            </div>
            <div>
              <div className="text-sm font-semibold text-gray-900">
                {parentObject || action.label}
              </div>
              <div className="text-sm text-gray-500">
                {previewLoading ? 'Preparing preview...' : 'Ready'}
              </div>
            </div>
          </div>
        </div>

        {childObject && (
          <div className="rounded-lg border border-gray-200 bg-white p-4">
            <div className="flex items-center gap-3">
              <div className="rounded-lg bg-emerald-50 p-2 text-emerald-700">
                <PackageCheck className="h-5 w-5" />
              </div>
              <div>
                <div className="text-sm font-semibold text-gray-900">
                  {childObject}
                </div>
                <div className="text-sm text-gray-500">
                  {childCount == null ? 'Included when available' : `${childCount} row${childCount === 1 ? '' : 's'}`}
                </div>
              </div>
            </div>
          </div>
        )}
      </div>
    </BaseModal>
  );
};
