/**
 * Runtime form fields — shared by Human Task input.form and workflow list trigger.form start.
 * Field rows match task.config.fields / graph node parameters.formFields shape from the backend.
 */

import React, { useEffect, useState } from 'react';
import { useApiRequest } from '../../../hooks/useApi';
import { loadClickupListTasksForDropdown, type ApiRequestFunction } from '../../../api/workflowApi';
import { normalizeFormFieldOptions } from '../nodes/form';
import { useLanguage } from '../../../providers/language/LanguageContext';

export type WorkflowRuntimeFormFieldRow = {
  name: string;
  type: string;
  label: string;
  required?: boolean;
  options?: unknown;
  clickupConnectionId?: string;
  clickupListId?: string;
  clickupStatusOptions?: Array<{ value: string; label: string }>;
};

export function relationshipTaskIdFromFormValue(v: unknown): string {
  if (v && typeof v === 'object' && !Array.isArray(v) && 'add' in v) {
    const a = (v as { add?: unknown[] }).add;
    if (Array.isArray(a) && a[0] != null && String(a[0]).trim()) return String(a[0]);
  }
  return '';
}

function InputFormClickupTaskField({
  connectionId,
  listId,
  value,
  onChange,
  request,
}: {
  connectionId: string;
  listId: string;
  value: unknown;
  onChange: (v: unknown) => void;
  request: ApiRequestFunction;
}) {
  const { t } = useLanguage();
  const [tasks, setTasks] = useState<Array<{ id: string; name: string }>>([]);
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState<string | null>(null);

  useEffect(() => {
    const cid = connectionId.trim();
    const lid = listId.trim();
    if (!cid || !lid) {
      setTasks([]);
      return;
    }
    let cancelled = false;
    setLoading(true);
    setErr(null);
    loadClickupListTasksForDropdown(request, cid, lid)
      .then((rows) => {
        if (!cancelled) setTasks(rows);
      })
      .catch(() => {
        if (!cancelled) {
          setTasks([]);
          setErr(t('Aufgaben konnten nicht geladen werden.'));
        }
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [request, connectionId, listId, t]);

  const sel = relationshipTaskIdFromFormValue(value);

  if (!connectionId.trim() || !listId.trim()) {
    return (
      <p style={{ fontSize: '0.85rem', color: 'var(--text-secondary, #666)' }}>
        {t('Für dieses Feld sind im Formular-Node ClickUp-Verbindung und Listen-ID gesetzt — bitte Workflow prüfen.')}
      </p>
    );
  }

  return (
    <>
      {err ? (
        <p style={{ fontSize: '0.85rem', color: 'var(--text-secondary, #c00)' }}>{err}</p>
      ) : null}
      {loading ? (
        <p style={{ fontSize: '0.85rem', color: 'var(--text-secondary, #666)' }}>{t('lade Aufgaben')}</p>
      ) : (
        <select
          value={sel}
          onChange={(e) => {
            const tid = e.target.value;
            if (!tid) onChange({ add: [], rem: [] });
            else onChange({ add: [tid], rem: [] });
          }}
        >
          <option value="">{t('Aufgabe wählen')}</option>
          {tasks.map((taskRow) => (
            <option key={taskRow.id} value={taskRow.id}>
              {taskRow.name}
            </option>
          ))}
        </select>
      )}
    </>
  );
}

export function useWorkflowRuntimeFormRequiredOk(
  fields: WorkflowRuntimeFormFieldRow[],
  formData: Record<string, unknown>
): boolean {
  const requiredFields = fields.filter((f) => f.required);
  return requiredFields.every((f) => {
    const v = formData[f.name];
    if (f.type === 'boolean') return true;
    if (f.type === 'clickup_tasks') {
      return relationshipTaskIdFromFormValue(v) !== '';
    }
    if (f.type === 'clickup_status') {
      return v !== undefined && v !== null && String(v).trim() !== '';
    }
    if (
      (f.type === 'select' || f.type === 'enum') &&
      normalizeFormFieldOptions(f.options).some((o) => String(o.value).trim() !== '')
    ) {
      return v !== undefined && v !== null && String(v).trim() !== '';
    }
    return v !== undefined && v !== null && String(v).trim() !== '';
  });
}

export interface WorkflowRuntimeFormFieldsProps {
  fields: WorkflowRuntimeFormFieldRow[];
  formData: Record<string, unknown>;
  setFormData: React.Dispatch<React.SetStateAction<Record<string, unknown>>>;
  formFieldsClassName: string;
}

/**
 * Renders the same controls as TaskCard input.form (no Popup — parent wraps if needed).
 */
export const WorkflowRuntimeFormFields: React.FC<WorkflowRuntimeFormFieldsProps> = ({
  fields,
  formData,
  setFormData,
  formFieldsClassName,
}) => {
  const { t } = useLanguage();
  const { request } = useApiRequest();

  const renderFormControl = (field: WorkflowRuntimeFormFieldRow): React.ReactNode => {
    const selectChoices = normalizeFormFieldOptions(field.options).filter((o) => String(o.value).trim() !== '');
    if (field.type === 'boolean') {
      return (
        <input
          type="checkbox"
          checked={(formData[field.name] as boolean) ?? false}
          onChange={(e) => setFormData((p) => ({ ...p, [field.name]: e.target.checked }))}
        />
      );
    }
    if (field.type === 'clickup_tasks' && request) {
      return (
        <InputFormClickupTaskField
          connectionId={field.clickupConnectionId ?? ''}
          listId={field.clickupListId ?? ''}
          value={formData[field.name]}
          onChange={(v) => setFormData((p) => ({ ...p, [field.name]: v }))}
          request={request}
        />
      );
    }
    if (
      field.type === 'clickup_status' &&
      Array.isArray(field.clickupStatusOptions) &&
      field.clickupStatusOptions.length > 0
    ) {
      return (
        <select
          value={(formData[field.name] as string) ?? ''}
          onChange={(e) => setFormData((p) => ({ ...p, [field.name]: e.target.value }))}
        >
          <option value="">{t('Status wählen')}</option>
          {field.clickupStatusOptions.map((o) => (
            <option key={o.value} value={o.value}>
              {o.label}
            </option>
          ))}
        </select>
      );
    }
    if ((field.type === 'select' || field.type === 'enum') && selectChoices.length > 0) {
      return (
        <select
          value={(formData[field.name] as string) ?? ''}
          onChange={(e) => setFormData((p) => ({ ...p, [field.name]: e.target.value }))}
        >
          <option value="">{t('Bitte wählen')}</option>
          {selectChoices.map((o) => (
            <option key={o.value} value={o.value}>
              {o.label || o.value}
            </option>
          ))}
        </select>
      );
    }
    return (
      <input
        type={field.type === 'number' ? 'number' : field.type === 'date' ? 'date' : 'text'}
        value={(formData[field.name] as string) ?? ''}
        onChange={(e) => setFormData((p) => ({ ...p, [field.name]: e.target.value }))}
      />
    );
  };

  return (
    <div className={formFieldsClassName}>
      {fields.map((f) => (
        <div key={f.name}>
          <label>
            {f.label || f.name}
            {f.required && ' *'}
          </label>
          {renderFormControl(f)}
        </div>
      ))}
    </div>
  );
};
