import { useState } from 'react';
import { StyleSheet, Switch, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { copyToClipboard } from '../../utils/copyToClipboard';
import { colors, radii, spacing } from '../../constants/theme';
import type { SelectOption } from '../../hooks/useSelectOptions';
import { BusinessHoursField } from './BusinessHoursField';
import { SwitchListField } from './SwitchListField';
import type { BusinessHours } from '../../utils/formValueHelpers';
import {
  autoGenerateSeedFields,
  buildAutoGenerateSeed,
  fetchGeneratedCode,
} from '../../services/codeGeneration';

export type FieldConfig = {
  key: string;
  label: string;
  type?: string;
  required?: boolean;
  options?: string[] | SelectOption[];
  source?: string;
  sourceParams?: Record<string, unknown>;
  placeholder?: string;
  span?: number;
  autoGenerate?: string | { type: string; seedFields?: string[] };
};

type Props = {
  field: FieldConfig;
  value: unknown;
  onChange: (value: unknown) => void; // eslint-disable-line @typescript-eslint/no-explicit-any
  readOnly?: boolean;
  formData?: Record<string, unknown>;
  resource?: string;
  recordId?: number | string;
};

function normalizeStaticOptions(options: FieldConfig['options'] = []): SelectOption[] {
  return options.map((option) => (
    typeof option === 'string' ? { value: option, label: option } : option
  ));
}

export function FormField({ field, value, onChange, readOnly, formData = {}, resource = '', recordId }: Props) {
  const type = field.type || 'text';
  const [generatingCode, setGeneratingCode] = useState(false);
  const [generateError, setGenerateError] = useState('');
  const [copied, setCopied] = useState(false);
  const [copyError, setCopyError] = useState('');

  const autoGenerateType = typeof field.autoGenerate === 'string'
    ? field.autoGenerate
    : field.autoGenerate?.type;

  const generateCode = async () => {
    if (!autoGenerateType || generatingCode || readOnly) return;

    setGeneratingCode(true);
    setGenerateError('');
    try {
      const seedFields = autoGenerateSeedFields(field);
      const seed = buildAutoGenerateSeed(formData, seedFields, autoGenerateType);
      const code = await fetchGeneratedCode({
        type: autoGenerateType,
        seed,
        recordId,
        resource,
      });
      onChange(code);
    } catch (error: unknown) {
      const err = error as { response?: { data?: { message?: string } }; message?: string };
      setGenerateError(err.response?.data?.message || err.message || 'Unable to generate code.');
    } finally {
      setGeneratingCode(false);
    }
  };

  if (type === 'business-hours') {
    return (
      <BusinessHoursField
        label={field.label}
        value={(value as BusinessHours) || {}}
        onChange={onChange}
        readOnly={readOnly}
      />
    );
  }

  if (type === 'switch-list') {
    const options = normalizeStaticOptions(field.options);
    const numericValues = field.key === 'service_ids' || field.key === 'staff_ids';

    return (
      <SwitchListField
        label={field.label}
        value={Array.isArray(value) ? value : []}
        options={options}
        onChange={onChange}
        numericValues={numericValues}
        readOnly={readOnly}
      />
    );
  }

  if (type === 'copy-readonly' || type === 'readonly') {
    const displayValue = value != null ? String(value) : '';
    const placeholder = field.key === 'share_url'
      ? 'Save the record to generate a widget URL.'
      : field.key === 'embed_html'
        ? 'Save the record to generate embed HTML.'
        : 'No value available yet.';

    const handleCopy = async () => {
      if (!displayValue || type === 'readonly') return;

      setCopyError('');
      const ok = await copyToClipboard(displayValue);
      if (!ok) {
        setCopyError('Unable to copy to clipboard.');
        return;
      }

      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    };

    return (
      <View style={styles.wrap}>
        <Text style={styles.label}>{field.label}</Text>
        <View style={styles.copyReadonlyValue}>
          <Text style={styles.copyReadonlyText} selectable>
            {displayValue || placeholder}
          </Text>
        </View>
        {type === 'copy-readonly' ? (
          <TouchableOpacity
            style={[styles.copyButton, (!displayValue || readOnly) && styles.generateButtonDisabled]}
            onPress={handleCopy}
            disabled={!displayValue || readOnly}
          >
            <Text style={styles.copyButtonText}>{copied ? 'Copied' : 'Copy'}</Text>
          </TouchableOpacity>
        ) : null}
        {copyError ? <Text style={styles.generateError}>{copyError}</Text> : null}
      </View>
    );
  }

  if (type === 'checkbox') {
    return (
      <View style={styles.row}>
        <Text style={styles.label}>{field.label}</Text>
        <Switch
          value={Boolean(value)}
          onValueChange={(v) => onChange(v)}
          disabled={readOnly}
          trackColor={{ true: colors.primary }}
        />
      </View>
    );
  }

  if (type === 'select' && field.options) {
    const opts = normalizeStaticOptions(field.options);
    return (
      <View style={styles.wrap}>
        <Text style={styles.label}>
          {field.label}
          {field.required ? ' *' : ''}
        </Text>
        <View style={styles.chips}>
          {opts.map((opt) => {
            const selected = String(value) === String(opt.value);
            return (
              <Text
                key={String(opt.value)}
                style={[styles.chip, selected && styles.chipActive]}
                onPress={readOnly ? undefined : () => onChange(opt.value)}
              >
                {opt.label}
              </Text>
            );
          })}
        </View>
      </View>
    );
  }

  if (type === 'textarea') {
    return (
      <View style={styles.wrap}>
        <Text style={styles.label}>
          {field.label}
          {field.required ? ' *' : ''}
        </Text>
        <TextInput
          style={[styles.input, styles.textarea]}
          multiline
          numberOfLines={4}
          value={value != null ? String(value) : ''}
          onChangeText={(t) => onChange(t)}
          editable={!readOnly}
          placeholder={field.placeholder}
          placeholderTextColor={colors.textMuted}
        />
      </View>
    );
  }

  const keyboardType =
    type === 'email' ? 'email-address' : type === 'tel' || type === 'number' ? 'numeric' : 'default';

  return (
    <View style={styles.wrap}>
      <Text style={styles.label}>
        {field.label}
        {field.required ? ' *' : ''}
      </Text>
      <View style={autoGenerateType ? styles.inputGroup : undefined}>
        <TextInput
          style={[styles.input, autoGenerateType ? styles.inputWithButton : null]}
          value={value != null ? String(value) : ''}
          onChangeText={(t) => onChange(type === 'number' ? (t === '' ? '' : Number(t)) : t)}
          editable={!readOnly}
          keyboardType={keyboardType}
          secureTextEntry={type === 'password'}
          placeholder={field.placeholder}
          placeholderTextColor={colors.textMuted}
          autoCapitalize={type === 'email' ? 'none' : 'sentences'}
        />
        {autoGenerateType ? (
          <TouchableOpacity
            style={[styles.generateButton, (readOnly || generatingCode) && styles.generateButtonDisabled]}
            onPress={generateCode}
            disabled={readOnly || generatingCode}
          >
            <Text style={styles.generateButtonText}>{generatingCode ? '...' : 'Generate'}</Text>
          </TouchableOpacity>
        ) : null}
      </View>
      {generateError ? <Text style={styles.generateError}>{generateError}</Text> : null}
    </View>
  );
}

const styles = StyleSheet.create({
  wrap: { marginBottom: spacing.md },
  label: { fontSize: 14, fontWeight: '600', color: colors.text, marginBottom: spacing.xs },
  input: {
    backgroundColor: colors.surface,
    borderWidth: 1,
    borderColor: colors.border,
    borderRadius: radii.md,
    paddingHorizontal: spacing.md,
    paddingVertical: 12,
    fontSize: 16,
    color: colors.text,
  },
  textarea: { minHeight: 100, textAlignVertical: 'top' },
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: spacing.md,
  },
  chips: { flexDirection: 'row', flexWrap: 'wrap', gap: spacing.sm },
  chip: {
    paddingHorizontal: 12,
    paddingVertical: 8,
    borderRadius: radii.pill,
    backgroundColor: colors.border,
    color: colors.text,
    overflow: 'hidden',
  },
  chipActive: { backgroundColor: colors.primaryLight, color: colors.primaryDark, fontWeight: '600' },
  inputGroup: { flexDirection: 'row', alignItems: 'stretch', gap: spacing.sm },
  inputWithButton: { flex: 1 },
  generateButton: {
    alignSelf: 'stretch',
    justifyContent: 'center',
    paddingHorizontal: spacing.md,
    borderRadius: radii.md,
    borderWidth: 1,
    borderColor: colors.primary,
    backgroundColor: colors.surface,
  },
  generateButtonDisabled: { opacity: 0.6 },
  generateButtonText: { color: colors.primary, fontWeight: '600', fontSize: 14 },
  generateError: { color: colors.danger, fontSize: 12, marginTop: spacing.xs },
  copyReadonlyValue: {
    backgroundColor: colors.surface,
    borderColor: colors.border,
    borderRadius: radii.md,
    borderWidth: 1,
    marginBottom: spacing.sm,
    paddingHorizontal: spacing.md,
    paddingVertical: 12,
  },
  copyReadonlyText: {
    color: colors.textMuted,
    fontSize: 14,
    lineHeight: 20,
  },
  copyButton: {
    alignSelf: 'flex-start',
    borderColor: colors.primary,
    borderRadius: radii.md,
    borderWidth: 1,
    paddingHorizontal: spacing.md,
    paddingVertical: 10,
  },
  copyButtonText: { color: colors.primary, fontWeight: '600', fontSize: 14 },
});
