import i18n from '@/i18n';
import dayjs from 'dayjs';
import { BlurView } from 'expo-blur';
import * as Clipboard from 'expo-clipboard';
import { Image } from 'expo-image';
import * as ImagePicker from 'expo-image-picker';
import { LinearGradient } from 'expo-linear-gradient';
import { useLocalSearchParams, useRouter } from 'expo-router';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Alert,
  KeyboardAvoidingView,
  Modal,
  Platform,
  ScrollView,
  StyleSheet,
  Switch,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { HeaderBar } from '@/components/ui/HeaderBar';
import { Colors } from '@/constants/Colors';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
import { useCosUpload } from '@/hooks/useCosUpload';
import { useI18n } from '@/hooks/useI18n';
import {
  ChallengeType,
  type CreateCustomChallengePayload,
  type UpdateCustomChallengePayload,
} from '@/services/challengesApi';
import { store } from '@/store';
import {
  createCustomChallengeThunk,
  fetchChallenges,
  selectChallengeById,
  selectCreateChallengeError,
  selectCreateChallengeStatus,
  selectUpdateChallengeError,
  selectUpdateChallengeStatus,
  updateCustomChallengeThunk
} from '@/store/challengesSlice';
import { Toast } from '@/utils/toast.utils';

const getTypeOptions = (t: (key: string) => string): { value: ChallengeType; label: string; accent: string }[] => [
  { value: ChallengeType.WATER, label: t('challenges.createCustom.typeLabels.water'), accent: '#5E8BFF' },
  { value: ChallengeType.EXERCISE, label: t('challenges.createCustom.typeLabels.exercise'), accent: '#6B6CFF' },
  { value: ChallengeType.DIET, label: t('challenges.createCustom.typeLabels.diet'), accent: '#38BDF8' },
  { value: ChallengeType.SLEEP, label: t('challenges.createCustom.typeLabels.sleep'), accent: '#7C3AED' },
  { value: ChallengeType.MOOD, label: t('challenges.createCustom.typeLabels.mood'), accent: '#F97316' },
  { value: ChallengeType.WEIGHT, label: t('challenges.createCustom.typeLabels.weight'), accent: '#22C55E' },
  { value: ChallengeType.CUSTOM, label: t('challenges.createCustom.typeLabels.custom'), accent: '#8B5CF6' },
];

const FALLBACK_IMAGE =
  'https://images.unsplash.com/photo-1506126613408-eca07ce68773?auto=format&fit=crop&w=1200&q=80';

type PickerType = 'start' | 'end' | null;

export default function CreateCustomChallengeScreen() {
  const { id, mode } = useLocalSearchParams<{ id?: string; mode?: 'edit' }>();
  const isEditMode = mode === 'edit' && !!id;
  
  const theme = (useColorScheme() ?? 'light') as 'light' | 'dark';
  const colorTokens = Colors[theme];
  const dispatch = useAppDispatch();
  const router = useRouter();
  const insets = useSafeAreaInsets();
  const createStatus = useAppSelector(selectCreateChallengeStatus);
  const createError = useAppSelector(selectCreateChallengeError);
  const updateError = useAppSelector(selectUpdateChallengeError);
  const updateStatus = useAppSelector(selectUpdateChallengeStatus);
  const inlineError = isEditMode ? updateError : createError;

  const isCreating = createStatus === 'loading';
  const isUpdating = updateStatus === 'loading';
  const { t } = useI18n();
  const typeOptions = useMemo(() => getTypeOptions(t), [t]);

  const today = useMemo(() => dayjs().startOf('day').toDate(), []);
  const defaultEnd = useMemo(() => dayjs().add(21, 'day').startOf('day').toDate(), []);

  const [title, setTitle] = useState('');
  const [image, setImage] = useState<string | undefined>(FALLBACK_IMAGE);
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const { upload, uploading } = useCosUpload({ prefix: 'images/challenges' });
  const [type, setType] = useState<ChallengeType>(ChallengeType.WATER);
  const [startDate, setStartDate] = useState<Date>(today);
  const [endDate, setEndDate] = useState<Date>(defaultEnd);
  const [targetValue, setTargetValue] = useState('');
  const [minimumCheckInDays, setMinimumCheckInDays] = useState('');
  const [requirementLabel, setRequirementLabel] = useState('');
  const [summary, setSummary] = useState('');
  const [progressUnit, setProgressUnit] = useState('');
  const [periodLabel, setPeriodLabel] = useState('');
  const [periodEdited, setPeriodEdited] = useState(false);
  const [rankingDescription] = useState(t('challenges.createCustom.rankingDescription'));
  const [isPublic, setIsPublic] = useState(true);
  const [maxParticipants, setMaxParticipants] = useState('100');
  const [minimumEdited, setMinimumEdited] = useState(false);

  const [shareCode, setShareCode] = useState<string | null>(null);
  const [shareModalVisible, setShareModalVisible] = useState(false);
  const [createdChallengeId, setCreatedChallengeId] = useState<string | null>(null);

  const [pickerType, setPickerType] = useState<PickerType>(null);

  // 编辑模式下预填充数据
  useEffect(() => {
    if (isEditMode && id) {
      const challengeSelector = selectChallengeById(id);
      const challenge = challengeSelector(store.getState());
      if (challenge) {
        setTitle(challenge.title || '');
        setImage(challenge.image);
        setType(challenge.type);
        setStartDate(new Date(challenge.startAt || Date.now()));
        setEndDate(new Date(challenge.endAt || Date.now()));
        setTargetValue(String(challenge.progress?.target || ''));
        setMinimumCheckInDays(String(challenge.minimumCheckInDays || ''));
        setSummary(challenge.summary || '');
        setProgressUnit(challenge.unit || '');
        setPeriodLabel(challenge.periodLabel || '');
        setIsPublic(challenge.isPublic ?? true);
        setMaxParticipants(challenge.maxParticipants?.toString() || '100');
      }
    }
  }, [isEditMode, id]);

  const durationDays = useMemo(
    () =>
      Math.max(
        1,
        dayjs(endDate).startOf('day').diff(dayjs(startDate).startOf('day'), 'day') + 1
      ),
    [startDate, endDate]
  );
  const durationLabel = useMemo(() => t('challenges.createCustom.durationDays', { days: durationDays }), [durationDays, t]);

  useEffect(() => {
    if (!periodEdited) {
      setPeriodLabel(t('challenges.createCustom.durationDaysChallenge', { days: durationDays }));
    }
    if (!minimumEdited) {
      setMinimumCheckInDays(String(durationDays));
    }
  }, [durationDays, minimumEdited, periodEdited, t]);

  const handleConfirmDate = (date: Date) => {
    if (!pickerType) return;
    const normalized = dayjs(date).startOf('day');
    if (pickerType === 'start') {
      const nextStart = normalized.isAfter(dayjs(), 'day')
        ? normalized
        : dayjs().add(1, 'day').startOf('day');
      setStartDate(nextStart.toDate());
      if (dayjs(endDate).isSameOrBefore(nextStart)) {
        const nextEnd = nextStart.add(20, 'day').toDate();
        setEndDate(nextEnd);
      }
    } else {
      const minEnd = dayjs(startDate).add(1, 'day').startOf('day');
      const nextEnd = normalized.isAfter(minEnd) ? normalized : minEnd;
      setEndDate(nextEnd.toDate());
    }
    setPickerType(null);
  };

  const handleSubmit = async () => {
    if (isCreating || isUpdating) return;
    if (!title.trim()) {
      Toast.warning(t('challenges.createCustom.alerts.titleRequired'));
      return;
    }


    const startTimestamp = dayjs(startDate).valueOf();
    const endTimestamp = dayjs(endDate).valueOf();
    if (endTimestamp <= startTimestamp) {
      Toast.warning(t('challenges.createCustom.alerts.endTimeError'));
      return;
    }

    const target = Number(targetValue);
    if (!Number.isFinite(target) || target < 1 || target > 1000) {
      Toast.warning(t('challenges.createCustom.alerts.targetValueError'));
      return;
    }

    const minDays = Number(minimumCheckInDays) || durationDays;
    if (!Number.isFinite(minDays) || minDays < 1 || minDays > 365) {
      Toast.warning(t('challenges.createCustom.alerts.minimumDaysError'));
      return;
    }
    if (minDays > durationDays) {
      Toast.warning(t('challenges.createCustom.alerts.minimumDaysExceedError'));
      return;
    }

    const maxP = maxParticipants ? Number(maxParticipants) : null;
    if (maxP !== null && (!Number.isFinite(maxP) || maxP < 2 || maxP > 10000)) {
      Toast.warning(t('challenges.createCustom.alerts.participantsError'));
      return;
    }

    const safeTitle = title.trim() || t('challenges.createCustom.defaultTitle');
    const payload: CreateCustomChallengePayload = {
      title: safeTitle,
      type,
      image: image?.trim() || undefined,
      startAt: startTimestamp,
      endAt: endTimestamp,
      targetValue: target,
      minimumCheckInDays: minDays,
      durationLabel,
      requirementLabel: '',
      summary: summary.trim() || undefined,
      progressUnit: progressUnit.trim(),
      periodLabel: periodLabel.trim() || undefined,
      rankingDescription: rankingDescription.trim() || undefined,
      isPublic,
      maxParticipants: maxP,
    };

    const updatePayload: UpdateCustomChallengePayload = {
      title: safeTitle,
      image: image?.trim() || undefined,
      summary: summary.trim() || undefined,
      isPublic,
      maxParticipants: maxP ?? undefined,
    };

    try {
      if (isEditMode && id) {
        await dispatch(updateCustomChallengeThunk({ id, payload: updatePayload })).unwrap();
        Toast.success(t('challenges.createCustom.alerts.updateSuccess'));
        dispatch(fetchChallenges());
        return;
      }

      const created = await dispatch(createCustomChallengeThunk(payload)).unwrap();
      setShareCode(created.shareCode ?? null);
      setCreatedChallengeId(created.id);
      setShareModalVisible(true);
      Toast.success(t('challenges.createCustom.alerts.createSuccess'));
      dispatch(fetchChallenges());
    } catch (error) {
      const message = typeof error === 'string' ? error : t('challenges.createCustom.alerts.createFailed');
      Toast.error(message);
    }
  };

  const handleCopyShareCode = async () => {
    if (!shareCode) return;
    await Clipboard.setStringAsync(shareCode);
    Toast.success(t('challenges.createCustom.shareModal.copyCode'));
  };

  const handleTargetInputChange = (value: string) => {
    const digits = value.replace(/\D/g, '');
    if (!digits) {
      setTargetValue('');
      return;
    }
    const num = Math.min(1000, parseInt(digits, 10));
    setTargetValue(String(num));
  };

  const handleMinimumDaysChange = (value: string) => {
    const digits = value.replace(/\D/g, '');
    if (!digits) {
      setMinimumCheckInDays('');
      setMinimumEdited(true);
      return;
    }
    const num = Math.max(1, Math.min(365, parseInt(digits, 10)));
    if (num > durationDays) {
      setMinimumCheckInDays(String(durationDays));
      setMinimumEdited(true);
      return;
    }
    setMinimumEdited(true);
    setMinimumCheckInDays(String(num));
  };

  const handlePickImage = useCallback(() => {
    Alert.alert(
      t('challenges.createCustom.imageUpload.selectSource'),
      t('challenges.createCustom.imageUpload.selectMessage'),
      [
        {
          text: t('challenges.createCustom.imageUpload.camera'),
          onPress: async () => {
            try {
              const permission = await ImagePicker.requestCameraPermissionsAsync();
              if (permission.status !== 'granted') {
                Alert.alert(t('challenges.createCustom.imageUpload.cameraPermission'), t('challenges.createCustom.imageUpload.cameraPermissionMessage'));
                return;
              }
              const result = await ImagePicker.launchCameraAsync({
                allowsEditing: true,
                quality: 0.6,
                aspect: [16, 9],
              });
              if (result.canceled || !result.assets?.length) return;
              const asset = result.assets[0];
              setImagePreview(asset.uri);
              setImage(undefined);
              try {
                const { url } = await upload(
                  {
                    uri: asset.uri,
                    name: asset.fileName ?? `challenge-${Date.now()}.jpg`,
                    type: asset.mimeType ?? 'image/jpeg',
                  },
                  { prefix: 'images/challenges' }
                );
                setImage(url);
                setImagePreview(null);
              } catch (error) {
                console.error('[CHALLENGE] 封面上传失败', error);
                Alert.alert(t('challenges.createCustom.imageUpload.uploadFailed'), t('challenges.createCustom.imageUpload.uploadFailedMessage'));
              }
            } catch (error) {
              console.error('[CHALLENGE] 拍照失败', error);
              Alert.alert(t('challenges.createCustom.imageUpload.cameraFailed'), t('challenges.createCustom.imageUpload.cameraFailedMessage'));
            }
          },
        },
        {
          text: t('challenges.createCustom.imageUpload.album'),
          onPress: async () => {
            try {
              const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
              if (permission.status !== 'granted') {
                Alert.alert(t('challenges.createCustom.imageUpload.cameraPermission'), t('challenges.createCustom.imageUpload.albumPermissionMessage'));
                return;
              }
              const result = await ImagePicker.launchImageLibraryAsync({
                mediaTypes: ['images'],
                quality: 0.9,
              });
              if (result.canceled || !result.assets?.length) return;
              const asset = result.assets[0];
              setImagePreview(asset.uri);
              setImage(undefined);
              try {
                const { url } = await upload(
                  {
                    uri: asset.uri,
                    name: asset.fileName ?? `challenge-${Date.now()}.jpg`,
                    type: asset.mimeType ?? 'image/jpeg',
                  },
                  { prefix: 'images/challenges' }
                );
                setImage(url);
                setImagePreview(null);
              } catch (error) {
                console.error('[CHALLENGE] 封面上传失败', error);
                Alert.alert(t('challenges.createCustom.imageUpload.uploadFailed'), t('challenges.createCustom.imageUpload.uploadFailedMessage'));
              }
            } catch (error) {
              console.error('[CHALLENGE] 选择封面失败', error);
              Alert.alert(t('challenges.createCustom.imageUpload.selectFailed'), t('challenges.createCustom.imageUpload.selectFailedMessage'));
            }
          },
        },
        { text: t('challenges.createCustom.imageUpload.cancel'), style: 'cancel' },
      ],
      { cancelable: true }
    );
  }, [upload, t]);

  const handleViewChallenge = () => {
    setShareModalVisible(false);
    if (createdChallengeId) {
      router.replace({ pathname: '/challenges/[id]', params: { id: createdChallengeId } });
    }
  };

  const renderField = (
    label: string,
    value: string,
    onChange: (val: string) => void,
    placeholder?: string,
    keyboardType: 'default' | 'numeric' = 'default',
    onFocus?: () => void
  ) => (
    <View style={styles.fieldBlock}>
      <Text style={styles.fieldLabel}>{label}</Text>
      <TextInput
        value={value}
        onChangeText={onChange}
        placeholder={placeholder}
        placeholderTextColor="#9ca3af"
        style={styles.input}
        keyboardType={keyboardType}
        onFocus={onFocus}
      />
    </View>
  );

  const renderTextarea = (
    label: string,
    value: string,
    onChange: (val: string) => void,
    placeholder?: string
  ) => (
    <View style={styles.fieldBlock}>
      <Text style={styles.fieldLabel}>{label}</Text>
      <TextInput
        value={value}
        onChangeText={onChange}
        placeholder={placeholder}
        placeholderTextColor="#9ca3af"
        style={[styles.input, styles.textarea]}
        multiline
        textAlignVertical="top"
      />
    </View>
  );

  const progressMeta = `${durationDays} ${t('challenges.createCustom.dayUnit')}${progressUnit ? ` · ${progressUnit}` : ''}`;
  const heroImageSource = imagePreview || image || FALLBACK_IMAGE;

  return (
    <View style={[styles.screen, { backgroundColor: colorTokens.pageBackgroundEmphasis }]}>
      <LinearGradient
        colors={[colorTokens.backgroundGradientStart, colorTokens.backgroundGradientEnd]}
        style={StyleSheet.absoluteFillObject}
      />
      <HeaderBar title={isEditMode ? t('challenges.createCustom.editTitle') : t('challenges.createCustom.title')} transparent />
      <KeyboardAvoidingView
        style={{ flex: 1 }}
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
        keyboardVerticalOffset={80}
      >
        <ScrollView
          showsVerticalScrollIndicator={false}
          contentContainerStyle={[
            styles.scrollContent,
            { paddingBottom: (Platform.OS === 'ios' ? 180 : 140) + insets.bottom },
          ]}
        >
          <View style={styles.heroContainer}>
            <Image
              source={{ uri: heroImageSource }}
              style={styles.heroImage}
              cachePolicy={'memory-disk'}
            />
            <LinearGradient
              colors={['rgba(0,0,0,0.35)', 'rgba(0,0,0,0.15)', 'rgba(244, 246, 255, 1)']}
              style={StyleSheet.absoluteFillObject}
            />
            <View style={styles.heroOverlay}>
              <Text style={styles.heroKicker}>{t('challenges.customChallenges')}</Text>
              <Text style={styles.heroTitle}>{title || t('challenges.createCustom.yourChallenge')}</Text>
              <Text style={styles.heroMeta}>{progressMeta}</Text>
            </View>
          </View>

          <View style={styles.formCard}>
            <View style={styles.formHeader}>
              <Text style={styles.sectionTitle}>{t('challenges.createCustom.basicInfo')}</Text>
              {inlineError ? <Text style={styles.inlineError}>{inlineError}</Text> : null}
            </View>
            {renderField(t('challenges.createCustom.fields.title'), title, setTitle, t('challenges.createCustom.fields.titlePlaceholder'))}
            <View style={styles.fieldBlock}>
              <Text style={styles.fieldLabel}>{t('challenges.createCustom.fields.coverImage')}</Text>
              <View style={styles.uploadRow}>
                <TouchableOpacity
                  activeOpacity={0.9}
                  style={[styles.uploadButton, uploading && styles.uploadButtonDisabled]}
                  onPress={handlePickImage}
                  disabled={uploading}
                >
                  <Text style={styles.uploadButtonLabel}>{uploading ? t('challenges.createCustom.imageUpload.uploading') : t('challenges.createCustom.fields.uploadCover')}</Text>
                </TouchableOpacity>
                {image || imagePreview ? (
                  <TouchableOpacity
                    activeOpacity={0.8}
                    onPress={() => {
                      setImagePreview(null);
                      setImage(undefined);
                    }}
                  >
                    <Text style={styles.clearUpload}>{t('challenges.createCustom.imageUpload.clear')}</Text>
                  </TouchableOpacity>
                ) : null}
              </View>
              <Text style={styles.helperText}>{t('challenges.createCustom.imageUpload.helper')}</Text>
            </View>
            {renderTextarea(t('challenges.createCustom.fields.challengeDescription'), summary, setSummary, t('challenges.createCustom.fields.descriptionPlaceholder'))}
          </View>

          <View style={styles.formCard}>
            <Text style={styles.sectionTitle}>{t('challenges.createCustom.challengeSettings')}</Text>

            <View style={styles.fieldBlock}>
              <Text style={styles.fieldLabel}>{t('challenges.createCustom.fields.challengeType')}</Text>
              <View style={styles.chipRow}>
                {typeOptions.map((option) => {
                  const active = option.value === type;
                  return (
                    <TouchableOpacity
                      key={option.value}
                      activeOpacity={0.9}
                      onPress={() => !isEditMode && setType(option.value)}
                      disabled={isEditMode}
                      style={[
                        styles.chip,
                        active && { backgroundColor: `${option.accent}1A`, borderColor: option.accent },
                        isEditMode && styles.chipDisabled,
                      ]}
                    >
                      <Text
                        style={[
                          styles.chipLabel,
                          active && { color: option.accent, fontWeight: '700' },
                          isEditMode && styles.chipLabelDisabled,
                        ]}
                      >
                        {option.label}
                      </Text>
                    </TouchableOpacity>
                  );
                })}
              </View>
              <Text style={styles.helperText}>{t('challenges.createCustom.fields.challengeTypeHelper')}</Text>
            </View>

            <View style={styles.fieldBlock}>
              <Text style={styles.fieldLabel}>{t('challenges.createCustom.fields.timeRange')}</Text>
              <View style={styles.dateRow}>
                <TouchableOpacity
                  activeOpacity={0.9}
                  style={styles.datePill}
                  onPress={() => setPickerType('start')}
                >
                  <Text style={styles.dateLabel}>{t('challenges.createCustom.fields.start')}</Text>
                  <Text style={styles.dateValue}>{dayjs(startDate).format('YYYY.MM.DD')}</Text>
                </TouchableOpacity>
                <TouchableOpacity
                  activeOpacity={0.9}
                  style={styles.datePill}
                  onPress={() => setPickerType('end')}
                >
                  <Text style={styles.dateLabel}>{t('challenges.createCustom.fields.end')}</Text>
                  <Text style={styles.dateValue}>{dayjs(endDate).format('YYYY.MM.DD')}</Text>
                </TouchableOpacity>
              </View>
            </View>

            <View style={styles.inlineFields}>
              <View style={styles.fieldBlock}>
                <Text style={styles.fieldLabel}>{t('challenges.createCustom.fields.duration')}</Text>
                <View style={styles.readonlyPill}>
                  <Text style={styles.readonlyText}>{durationLabel}</Text>
                </View>
              </View>
              {renderField(t('challenges.createCustom.fields.periodLabel'), periodLabel, (v) => {
                setPeriodEdited(true);
                setPeriodLabel(v);
              }, t('challenges.createCustom.fields.periodLabelPlaceholder'))}
            </View>

            <View style={styles.fieldBlock}>
              <Text style={styles.fieldLabel}>{t('challenges.createCustom.fields.dailyTargetAndUnit')}</Text>
              <View style={styles.targetUnitRow}>
                <TextInput
                  value={targetValue}
                  onChangeText={handleTargetInputChange}
                  placeholder={t('challenges.createCustom.fields.dailyTargetPlaceholder')}
                  placeholderTextColor="#9ca3af"
                  style={[styles.input, styles.targetInput]}
                  keyboardType="numeric"
                />
                <TextInput
                  value={progressUnit}
                  onChangeText={setProgressUnit}
                  placeholder={t('challenges.createCustom.fields.unitPlaceholder')}
                  placeholderTextColor="#9ca3af"
                  style={[styles.input, styles.unitInput]}
                />
              </View>
              <Text style={styles.helperText}>{t('challenges.createCustom.fields.unitHelper')}</Text>
            </View>

            {renderField(t('challenges.createCustom.fields.minimumCheckInDays'), minimumCheckInDays, handleMinimumDaysChange, t('challenges.createCustom.fields.minimumCheckInDaysPlaceholder'), 'numeric')}

          </View>

          <View style={styles.formCard}>
            <Text style={styles.sectionTitle}>{t('challenges.createCustom.displayInteraction')}</Text>
            <View style={styles.inlineFields}>
              {renderField(t('challenges.createCustom.fields.maxParticipants'), maxParticipants, (v) => {
                const digits = v.replace(/\D/g, '');
                if (!digits) {
                  setMaxParticipants('');
                  return;
                }
                setMaxParticipants(String(parseInt(digits, 10)));
              }, t('challenges.createCustom.fields.noLimit'), 'numeric')}
            </View>
            <View style={styles.switchRow}>
              <View>
                <Text style={styles.fieldLabel}>{t('challenges.createCustom.fields.isPublic')}</Text>
                <Text style={styles.switchHint}>{t('challenges.createCustom.fields.publicDescription')}</Text>
              </View>
              <Switch
                value={isPublic}
                onValueChange={setIsPublic}
                trackColor={{ true: colorTokens.primary, false: '#cbd5e1' }}
                thumbColor={isPublic ? '#ffffff' : undefined}
              />
            </View>
          </View>
        </ScrollView>
      </KeyboardAvoidingView>

      <View pointerEvents="box-none" style={[styles.floatingCTA, { paddingBottom: insets.bottom + 12 }]}>
        <BlurView intensity={14} tint="light" style={styles.floatingBlur}>
          <View style={styles.floatingContent}>
            <View style={styles.floatingCopy}>
              <Text style={styles.floatingTitle}>
                {isEditMode
                  ? t('challenges.createCustom.floatingCTA.editTitle')
                  : t('challenges.createCustom.floatingCTA.title')
                }
              </Text>
              <Text style={styles.floatingSubtitle}>
                {isEditMode
                  ? t('challenges.createCustom.floatingCTA.editSubtitle')
                  : t('challenges.createCustom.floatingCTA.subtitle')
                }
              </Text>
            </View>
            <TouchableOpacity
              activeOpacity={0.9}
              style={styles.floatingButton}
              onPress={handleSubmit}
              disabled={isCreating || isUpdating}
            >
              <LinearGradient
                colors={['#5E8BFF', '#6B6CFF']}
                start={{ x: 0, y: 0 }}
                end={{ x: 1, y: 1 }}
                style={styles.floatingButtonBackground}
              >
                <Text style={styles.floatingButtonLabel}>
                  {isCreating
                    ? t('challenges.createCustom.buttons.creating')
                    : isUpdating
                      ? t('challenges.createCustom.buttons.updating')
                      : isEditMode
                        ? t('challenges.createCustom.buttons.updateAndSave')
                        : t('challenges.createCustom.buttons.createAndGenerateCode')
                  }
                </Text>
              </LinearGradient>
            </TouchableOpacity>
          </View>
        </BlurView>
      </View>

      <DateTimePickerModal
        isVisible={pickerType !== null}
        mode="date"
        date={pickerType === 'end' ? endDate : startDate}
        minimumDate={pickerType === 'end' ? dayjs(startDate).add(1, 'day').toDate() : dayjs().add(1, 'day').toDate()}
        onConfirm={handleConfirmDate}
        onCancel={() => setPickerType(null)}
        locale={i18n.language}
        confirmTextIOS={t('challenges.createCustom.datePicker.confirm')}
        cancelTextIOS={t('challenges.createCustom.datePicker.cancel')}
      />

      <Modal
        visible={shareModalVisible}
        transparent
        animationType="fade"
        onRequestClose={() => setShareModalVisible(false)}
      >
        <View style={styles.modalOverlay}>
          <View style={styles.shareCard}>
            <Text style={styles.shareTitle}>{t('challenges.createCustom.shareModal.title')}</Text>
            <Text style={styles.shareSubtitle}>{t('challenges.createCustom.shareModal.subtitle')}</Text>
            <View style={styles.shareCodeBadge}>
              <Text style={styles.shareCode}>{shareCode ?? t('challenges.createCustom.shareModal.generatingCode')}</Text>
            </View>
            <View style={styles.shareActions}>
              <TouchableOpacity
                activeOpacity={0.85}
                style={styles.shareButtonGhost}
                onPress={handleCopyShareCode}
                disabled={!shareCode}
              >
                <Text style={styles.shareButtonGhostLabel}>{t('challenges.createCustom.shareModal.copyCode')}</Text>
              </TouchableOpacity>
              <TouchableOpacity
                activeOpacity={0.9}
                style={styles.shareButtonPrimary}
                onPress={handleViewChallenge}
              >
                <LinearGradient
                  colors={['#5E8BFF', '#6B6CFF']}
                  start={{ x: 0, y: 0 }}
                  end={{ x: 1, y: 1 }}
                  style={styles.shareButtonPrimary}
                >
                  <Text style={styles.shareButtonPrimaryLabel}>{t('challenges.createCustom.shareModal.viewChallenge')}</Text>
                </LinearGradient>
              </TouchableOpacity>
            </View>
            <TouchableOpacity
              style={styles.shareClose}
              activeOpacity={0.8}
              onPress={() => setShareModalVisible(false)}
            >
              <Text style={styles.shareCloseLabel}>{t('challenges.createCustom.shareModal.later')}</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  screen: {
    flex: 1,
  },
  scrollContent: {
    paddingBottom: 160,
  },
  heroContainer: {
    height: 260,
    width: '100%',
    overflow: 'hidden',
  },
  heroImage: {
    width: '100%',
    height: '100%',
  },
  heroOverlay: {
    position: 'absolute',
    bottom: 22,
    left: 20,
    right: 20,
  },
  heroKicker: {
    color: '#f8fafc',
    fontSize: 13,
    letterSpacing: 1.2,
    fontWeight: '700',
  },
  heroTitle: {
    marginTop: 8,
    fontSize: 26,
    fontWeight: '800',
    color: '#ffffff',
    textShadowColor: 'rgba(0,0,0,0.25)',
    textShadowOffset: { width: 0, height: 2 },
    textShadowRadius: 6,
  },
  heroMeta: {
    marginTop: 6,
    fontSize: 14,
    color: '#e2e8f0',
    fontWeight: '600',
  },
  formCard: {
    marginTop: 14,
    marginHorizontal: 20,
    padding: 18,
    borderRadius: 22,
    backgroundColor: '#ffffff',
    shadowColor: 'rgba(30, 41, 59, 0.12)',
    shadowOpacity: 0.2,
    shadowRadius: 20,
    shadowOffset: { width: 0, height: 12 },
    elevation: 8,
    gap: 10,
  },
  sectionTitle: {
    fontSize: 18,
    fontWeight: '800',
    color: '#0f172a',
  },
  fieldBlock: {
    gap: 6,
  },
  fieldLabel: {
    fontSize: 14,
    fontWeight: '700',
    color: '#0f172a',
  },
  input: {
    paddingHorizontal: 14,
    paddingVertical: 12,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    backgroundColor: '#f8fafc',
    fontSize: 15,
    color: '#111827',
  },
  targetUnitRow: {
    flexDirection: 'row',
    gap: 12,
  },
  targetInput: {
    flex: 1,
  },
  unitInput: {
    flex: 1,
  },
  textarea: {
    minHeight: 90,
  },
  chipRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
  },
  chip: {
    paddingHorizontal: 14,
    paddingVertical: 10,
    borderRadius: 14,
    backgroundColor: '#f8fafc',
    borderWidth: 1,
    borderColor: '#e5e7eb',
  },
  chipDisabled: {
    opacity: 0.5,
    backgroundColor: '#f1f5f9',
  },
  chipLabel: {
    fontSize: 13,
    color: '#334155',
  },
  chipLabelDisabled: {
    color: '#94a3b8',
  },
  uploadRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 12,
  },
  uploadButton: {
    paddingHorizontal: 14,
    paddingVertical: 10,
    borderRadius: 12,
    backgroundColor: '#EEF1FF',
    borderWidth: 1,
    borderColor: '#d1d5db',
  },
  uploadButtonDisabled: {
    opacity: 0.7,
  },
  uploadButtonLabel: {
    fontSize: 14,
    fontWeight: '700',
    color: '#4F5BD5',
  },
  clearUpload: {
    fontSize: 13,
    fontWeight: '600',
    color: '#9ca3af',
  },
  helperText: {
    marginTop: 6,
    fontSize: 12,
    color: '#6b7280',
  },
  dateRow: {
    flexDirection: 'row',
    gap: 12,
  },
  datePill: {
    flex: 1,
    padding: 12,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    backgroundColor: '#f8fafc',
  },
  dateLabel: {
    fontSize: 12,
    color: '#6b7280',
  },
  dateValue: {
    marginTop: 4,
    fontSize: 15,
    fontWeight: '700',
    color: '#0f172a',
  },
  readonlyPill: {
    marginTop: 6,
    paddingHorizontal: 14,
    paddingVertical: 10,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    backgroundColor: '#f8fafc',
  },
  readonlyText: {
    fontSize: 15,
    fontWeight: '700',
    color: '#0f172a',
  },
  inlineFields: {
    gap: 12,
  },
  switchRow: {
    marginTop: 6,
    padding: 12,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#e5e7eb',
    backgroundColor: '#f8fafc',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  switchHint: {
    marginTop: 4,
    fontSize: 12,
    color: '#6b7280',
  },
  formHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  inlineError: {
    fontSize: 12,
    color: '#ef4444',
  },
  floatingCTA: {
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    paddingHorizontal: 16,
    paddingTop: 10,
  },
  floatingBlur: {
    borderRadius: 24,
    overflow: 'hidden',
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.6)',
    backgroundColor: 'rgba(243, 244, 251, 0.9)',
  },
  floatingContent: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: 12,
    paddingHorizontal: 16,
    paddingVertical: 14,
  },
  floatingCopy: {
    flex: 1,
  },
  floatingTitle: {
    fontSize: 15,
    fontWeight: '800',
    color: '#0f172a',
  },
  floatingSubtitle: {
    marginTop: 4,
    fontSize: 12,
    color: '#6b7280',
  },
  floatingButton: {
    borderRadius: 16,
    overflow: 'hidden',
  },
  floatingButtonBackground: {
    paddingHorizontal: 18,
    paddingVertical: 12,
    borderRadius: 16,
    alignItems: 'center',
    justifyContent: 'center',
  },
  floatingButtonLabel: {
    fontSize: 14,
    fontWeight: '800',
    color: '#ffffff',
  },
  modalOverlay: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.35)',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 20,
  },
  shareCard: {
    width: '100%',
    padding: 20,
    borderRadius: 22,
    backgroundColor: '#ffffff',
    shadowColor: 'rgba(15, 23, 42, 0.18)',
    shadowOffset: { width: 0, height: 12 },
    shadowOpacity: 0.25,
    shadowRadius: 20,
    elevation: 12,
    alignItems: 'center',
    gap: 10,
  },
  shareTitle: {
    fontSize: 18,
    fontWeight: '800',
    color: '#0f172a',
  },
  shareSubtitle: {
    fontSize: 13,
    color: '#6b7280',
  },
  shareCodeBadge: {
    marginTop: 10,
    paddingHorizontal: 18,
    paddingVertical: 12,
    borderRadius: 16,
    backgroundColor: '#EEF1FF',
  },
  shareCode: {
    fontSize: 22,
    fontWeight: '800',
    color: '#4F5BD5',
    letterSpacing: 2,
  },
  shareActions: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: 12,
    width: '100%',
    marginTop: 8,
  },
  shareButtonGhost: {
    flex: 1,
    paddingVertical: 12,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#d1d5db',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#f8fafc',
  },
  shareButtonGhostLabel: {
    fontSize: 14,
    fontWeight: '700',
    color: '#475569',
  },
  shareButtonPrimary: {
    flex: 1,
    borderRadius: 14,
    overflow: 'hidden',
  },
  shareButtonPrimaryLabel: {
    textAlign: 'center',
    fontSize: 14,
    fontWeight: '800',
    color: '#ffffff',
    paddingVertical: 12,
  },
  shareClose: {
    marginTop: 8,
    paddingVertical: 10,
    paddingHorizontal: 12,
  },
  shareCloseLabel: {
    fontSize: 13,
    color: '#6b7280',
  },
});
