/**
 * Switch node config - RefSourceSelect für Datenquelle, Fälle mit Operator + Wert.
 * Gleicher Kontext wie IfElse: typabhängige Operatoren (z.B. Alter < 19, = 30).
 */

import React from 'react';
import type { NodeConfigRendererProps } from '../shared/types';
import { RefSourceSelect, getFieldType } from '../shared/RefSourceSelect';
import { useAutomation2DataFlow } from '../../context/Automation2DataFlowContext';
import { isRef, createValue } from '../shared/dataRef';
import { getMimeTypeOptionsFromUploadParams } from '../runtime/fileTypeMimeMapping';
import { operatorsForType } from '../shared/conditionOperators';
import styles from '../../editor/Automation2FlowEditor.module.css';

import { useLanguage } from '../../../../providers/language/LanguageContext';

export interface SwitchCase {
  operator: string;
  value?: string | number | boolean;
}

function normalizeCase(c: unknown): SwitchCase {
  if (c && typeof c === 'object' && 'operator' in (c as object)) {
    const o = c as SwitchCase;
    const v = o.value;
    const safeValue: string | number | boolean | undefined =
      typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' ? v : undefined;
    return { operator: o.operator ?? 'eq', value: safeValue };
  }
  const fallbackValue: string | number | boolean | undefined =
    typeof c === 'string' || typeof c === 'number' || typeof c === 'boolean' ? c : undefined;
  return { operator: 'eq', value: fallbackValue };
}

export const SwitchNodeConfig: React.FC<NodeConfigRendererProps> = ({ params, updateParam }) => {
  const { t } = useLanguage();
  const dataFlow = useAutomation2DataFlow();

  const valueParam = params.value;
  const ref = isRef(valueParam) ? valueParam : null;
  let staticValue: string | number = '';
  if (!ref && valueParam != null) {
    if (typeof valueParam === 'object' && 'value' in valueParam) {
      const v = (valueParam as { value: unknown }).value;
      staticValue = v !== undefined && v !== null ? String(v) : '';
    } else if (typeof valueParam === 'string' || typeof valueParam === 'number') {
      staticValue = valueParam;
    }
  }
  const rawCases = (params.cases as unknown[]) ?? [];
  const cases: SwitchCase[] = rawCases.map(normalizeCase);

  const fieldType = dataFlow ? getFieldType(ref, dataFlow.nodes, dataFlow.nodeOutputsPreview) : 'unknown';
  const operators = operatorsForType(fieldType);
  const isMimeTypeRef =
    ref && ref.path?.length >= 2 && ref.path[ref.path.length - 1] === 'mimeType';
  const sourceNode = ref && dataFlow
    ? dataFlow.nodes.find((n: { id: string; type?: string; parameters?: Record<string, unknown> }) => n.id === ref.nodeId)
    : null;
  const mimeTypeOptions =
    isMimeTypeRef && sourceNode?.type === 'input.upload' && sourceNode.parameters
      ? getMimeTypeOptionsFromUploadParams(sourceNode.parameters as Record<string, unknown>)
      : [];

  const setValue = (val: unknown) => {
    updateParam('value', val);
  };

  const setCases = (next: SwitchCase[]) => {
    updateParam('cases', next);
  };

  const handleRefChange = (newRef: { type: 'ref'; nodeId: string; path: (string | number)[] } | null) => {
    if (newRef) {
      setValue(newRef);
    } else {
      setValue(createValue(staticValue));
    }
  };

  const handleStaticValueChange = (v: string) => {
    setValue(createValue(fieldType === 'number' ? parseFloat(v) || 0 : v));
  };

  const handleCaseOperatorChange = (index: number, op: string) => {
    const opDef = operators.find((o) => o.value === op);
    const next = [...cases];
    next[index] = {
      operator: op,
      value: opDef?.needsValue ? cases[index]?.value : undefined,
    };
    setCases(next);
  };

  const handleCaseValueChange = (index: number, v: string | number | boolean) => {
    const next = [...cases];
    next[index] = {
      ...next[index],
      value: fieldType === 'number' ? (typeof v === 'number' ? v : parseFloat(String(v)) || 0)
        : fieldType === 'boolean' ? (v === true || v === 'true')
        : String(v),
    };
    setCases(next);
  };

  const renderCaseValueInput = (caseItem: SwitchCase, index: number) => {
    const val = caseItem.value;
    const valStr = String(val ?? '');

    if (mimeTypeOptions.length > 0) {
      return (
        <select
          value={valStr}
          onChange={(e) => handleCaseValueChange(index, e.target.value)}
          className={styles.startsInput}
        >
          <option value="">{t('MIME-Typ wählen')}</option>
          {mimeTypeOptions.map((o) => (
            <option key={o.value} value={o.value}>
              {o.label} ({o.value})
            </option>
          ))}
        </select>
      );
    }
    if (fieldType === 'number') {
      return (
        <input
          type="number"
          className={styles.startsInput}
          value={valStr}
          onChange={(e) => handleCaseValueChange(index, parseFloat(e.target.value) || 0)}
          placeholder="0"
        />
      );
    }
    if (fieldType === 'date') {
      return (
        <input
          type="date"
          className={styles.startsInput}
          value={valStr}
          onChange={(e) => handleCaseValueChange(index, e.target.value)}
        />
      );
    }
    if (fieldType === 'boolean') {
      return (
        <select
          value={val === true ? 'true' : val === false ? 'false' : ''}
          onChange={(e) => {
            const v = e.target.value;
            handleCaseValueChange(index, v === 'true' ? true : v === 'false' ? false : '');
          }}
          className={styles.startsInput}
        >
          <option value="">{t('Wählen')}</option>
          <option value="true">{t('Ja (true)')}</option>
          <option value="false">{t('Nein (false)')}</option>
        </select>
      );
    }
    return (
      <input
        type="text"
        className={styles.startsInput}
        value={valStr}
        onChange={(e) => handleCaseValueChange(index, e.target.value)}
        placeholder={isMimeTypeRef ? t('z.B. application/pdf') : t('Wert')}
      />
    );
  };

  const addCase = () => {
    const opDef = operators[0];
    const defaultVal = opDef?.needsValue
      ? (fieldType === 'number' ? 0 : fieldType === 'boolean' ? false : '')
      : undefined;
    setCases([
      ...cases,
      { operator: opDef?.value ?? 'eq', value: defaultVal },
    ]);
  };

  return (
    <div className={styles.ifElseConditionEditor}>
      <div className={styles.ifElseConditionRow}>
        <label>{t('Datenquelle')}</label>
        <RefSourceSelect
          value={ref}
          onChange={handleRefChange}
          placeholder={t('Feld zum Vergleich wählen')}
        />
      </div>

      {!ref && (
        <div className={styles.ifElseConditionRow}>
          <label>{t('Fester Wert (ohne Referenz)')}</label>
          <input
            type="text"
            value={String(staticValue ?? '')}
            onChange={(e) => handleStaticValueChange(e.target.value)}
            placeholder={t('z. B. CH oder 42')}
          />
        </div>
      )}

      <div className={styles.ifElseConditionRow}>
        <label>{t('Fälle / Reihenfolge / Ausgabe')}</label>
        <div className={styles.formFieldsList}>
          {cases.map((c, i) => {
            const opDef = operators.find((o) => o.value === c.operator) ?? operators[0];
            const needsValue = opDef?.needsValue ?? true;
            return (
              <div key={i} className={styles.formFieldRow}>
                <select
                  value={c.operator}
                  onChange={(e) => handleCaseOperatorChange(i, e.target.value)}
                  className={styles.startsInput}
                  style={{ minWidth: 140 }}
                >
                  {operators.map((o) => (
                    <option key={o.value} value={o.value}>
                      {o.label}
                    </option>
                  ))}
                </select>
                {needsValue && (
                  <div style={{ flex: 1 }}>
                    {renderCaseValueInput(c, i)}
                  </div>
                )}
                <button
                  type="button"
                  className={styles.formFieldRemoveButton}
                  onClick={() => setCases(cases.filter((_, j) => j !== i))}
                >
                  ✕
                </button>
              </div>
            );
          })}
          <button type="button" className={styles.startsAddBtn} onClick={addCase}>
            {t('+ Fall')}
          </button>
        </div>
      </div>
    </div>
  );
};
