import React from 'react';
import { SearchOutlined } from '@ant-design/icons';
import { Button, DatePicker, Form, FormProps, Input, Space } from 'antd';
import { agentAttrs } from './agentPanel/agentAttributes';

const { RangePicker } = DatePicker;

export interface SearchBarField {
  name: string;
  type: 'keyword' | 'dateRange' | 'custom';
  label?: string;
  placeholder?: string;
  component?: React.ReactNode;
  style?: React.CSSProperties;
}

export interface SearchBarRenderContext {
  /** Form props from parent */
  formProps: FormProps;
  /** Fields configuration */
  fields: SearchBarField[];
  /** Translation function */
  t: (key: string, defaultValue?: string) => string;
  /** Resource name */
  resourceName: string;
  /** Render a single field */
  renderField: (field: SearchBarField) => React.ReactNode;
  /** Default submit button */
  defaultSubmitButton: React.ReactNode;
}

export interface SearchBarProps {
  formProps: FormProps;
  fields?: SearchBarField[];
  /** Translation function */
  t?: (key: string, defaultValue?: string) => string;
  /** Resource name for i18n keys */
  resourceName?: string;
  /** Default placeholder for keyword search */
  searchPlaceholder?: string;
  /** Submit button text */
  submitText?: string;
  /** Custom children - if provided as function, gives full control */
  children?:
    | React.ReactNode
    | ((context: SearchBarRenderContext) => React.ReactNode);

  // Render props for fine-grained customization
  /** Custom render for keyword input */
  renderKeywordInput?: (
    field: SearchBarField,
    defaultInput: React.ReactNode,
  ) => React.ReactNode;
  /** Custom render for date range picker */
  renderDateRangePicker?: (
    field: SearchBarField,
    defaultPicker: React.ReactNode,
  ) => React.ReactNode;
  /** Custom render for submit button */
  renderSubmitButton?: (defaultButton: React.ReactNode) => React.ReactNode;
  /** Custom render for field wrapper (Form.Item) */
  renderFieldWrapper?: (
    field: SearchBarField,
    children: React.ReactNode,
  ) => React.ReactNode;
  /** Extra fields to render before submit button */
  extraFields?: React.ReactNode;
  /** Extra actions to render after submit button */
  extraActions?: React.ReactNode;
  /** Show submit button */
  showSubmitButton?: boolean;
  /** Custom form wrapper - if false, renders without Form wrapper */
  noFormWrapper?: boolean;
}

/**
 * Reusable search bar component for list pages
 *
 * @example
 * // Basic usage
 * <SearchBar
 *   formProps={searchFormProps}
 *   t={t}
 *   resourceName="audit"
 * />
 *
 * @example
 * // With custom render props
 * <SearchBar
 *   {...props}
 *   renderKeywordInput={(field, defaultInput) => (
 *     <MyCustomSearchInput placeholder={field.placeholder} />
 *   )}
 *   renderSubmitButton={(defaultButton) => (
 *     <Space>
 *       {defaultButton}
 *       <Button onClick={handleReset}>Reset</Button>
 *     </Space>
 *   )}
 *   extraActions={<Button onClick={handleAdvanced}>Advanced</Button>}
 * />
 *
 * @example
 * // Completely custom UI using children
 * <SearchBar formProps={formProps}>
 *   {({ fields, renderField, defaultSubmitButton }) => (
 *     <MyCustomSearchLayout>
 *       {fields.map(renderField)}
 *       {defaultSubmitButton}
 *     </MyCustomSearchLayout>
 *   )}
 * </SearchBar>
 */
export const SearchBar: React.FC<SearchBarProps> = ({
  formProps,
  fields,
  t = (key, defaultValue) => defaultValue || key,
  resourceName = '',
  searchPlaceholder = '',
  submitText,
  children,
  renderKeywordInput,
  renderDateRangePicker,
  renderSubmitButton,
  renderFieldWrapper,
  extraFields,
  extraActions,
  showSubmitButton = true,
  noFormWrapper = false,
}) => {
  // Default fields if none provided
  const defaultFields: SearchBarField[] = [
    {
      name: 'q',
      type: 'keyword',
      label: t(`resources.${resourceName}.search.q.title`, 'Search'),
      placeholder: t(
        `resources.${resourceName}.search.q.placeholder`,
        searchPlaceholder,
      ),
      style: { width: '100%', maxWidth: '300px' },
    },
    {
      name: 'createdAt',
      type: 'dateRange',
      label: t(`resources.${resourceName}.fields.createdAt`, 'createdAt'),
      style: { width: '100%', maxWidth: '400px' },
    },
  ];

  const fieldsToRender = fields || defaultFields;

  // Default submit button
  const defaultSubmitButton = (
    <Form.Item>
      <Button htmlType="submit" type="primary">
        {submitText || t('buttons.filter', 'Filter')}
      </Button>
    </Form.Item>
  );

  // Default field wrapper
  const defaultFieldWrapper = (
    field: SearchBarField,
    children: React.ReactNode,
  ) => (
    <Form.Item
      key={field.name}
      label={field.label}
      name={field.name}
      style={field.style}
    >
      {children}
    </Form.Item>
  );

  // Render a single field
  const renderField = (field: SearchBarField): React.ReactNode => {
    if (field.type === 'custom' && field.component) {
      const wrapper = renderFieldWrapper || defaultFieldWrapper;
      return (
        <React.Fragment key={field.name}>
          {wrapper(field, field.component)}
        </React.Fragment>
      );
    }

    if (field.type === 'dateRange') {
      const defaultPicker = <RangePicker />;
      const picker = renderDateRangePicker
        ? renderDateRangePicker(field, defaultPicker)
        : defaultPicker;

      const defaultLabel =
        field.label ||
        t(`resources.${resourceName}.fields.${field.name}`, field.name);
      const defaultStyle = field.style || { width: '100%', maxWidth: '400px' };

      if (renderFieldWrapper) {
        return (
          <React.Fragment key={field.name}>
            &nbsp;
            {renderFieldWrapper(
              { ...field, label: defaultLabel, style: defaultStyle },
              picker,
            )}
          </React.Fragment>
        );
      }

      return (
        <React.Fragment key={field.name}>
          &nbsp;
          <Form.Item
            label={defaultLabel}
            name={field.name}
            style={defaultStyle}
          >
            {picker}
          </Form.Item>
        </React.Fragment>
      );
    }

    // Default: keyword search
    const defaultLabel =
      field.label ||
      t(`resources.${resourceName}.search.${field.name}.title`, 'Search');
    const defaultPlaceholder =
      field.placeholder ||
      t(
        `resources.${resourceName}.search.${field.name}.placeholder`,
        searchPlaceholder,
      );
    const defaultStyle = field.style || { width: '100%', maxWidth: '300px' };

    const defaultInput = (
      <Input placeholder={defaultPlaceholder} prefix={<SearchOutlined />} />
    );

    const input = renderKeywordInput
      ? renderKeywordInput(
          { ...field, placeholder: defaultPlaceholder },
          defaultInput,
        )
      : defaultInput;

    if (renderFieldWrapper) {
      return (
        <React.Fragment key={field.name}>
          {renderFieldWrapper(
            { ...field, label: defaultLabel, style: defaultStyle },
            input,
          )}
        </React.Fragment>
      );
    }

    return (
      <Form.Item
        key={field.name}
        label={defaultLabel}
        name={field.name}
        style={defaultStyle}
      >
        {input}
      </Form.Item>
    );
  };

  // Build context for render function
  const context: SearchBarRenderContext = {
    formProps,
    fields: fieldsToRender,
    t,
    resourceName,
    renderField,
    defaultSubmitButton,
  };

  // If children is a function, call it with context
  if (typeof children === 'function') {
    const content = children(context);
    if (noFormWrapper) {
      return <>{content}</>;
    }
    return <Form {...formProps}>{content}</Form>;
  }

  // If children is provided as ReactNode, render it directly
  if (children) {
    if (noFormWrapper) {
      return <>{children}</>;
    }
    return <Form {...formProps}>{children}</Form>;
  }

  // Default rendering
  const content = (
    <Space wrap>
      {fieldsToRender.map(renderField)}
      {extraFields}
      &nbsp;
      {showSubmitButton &&
        (renderSubmitButton
          ? renderSubmitButton(defaultSubmitButton)
          : defaultSubmitButton)}
      {extraActions}
    </Space>
  );

  if (noFormWrapper) {
    return content;
  }

  return (
    <div {...agentAttrs({ type: 'list-search-bar', resource: resourceName })}>
      <Form {...formProps}>{content}</Form>
    </div>
  );
};

export default SearchBar;
