import React, { useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Image,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useLocalSearchParams, useRouter } from 'expo-router';
import { ArrowLeft, UploadCloud } from 'lucide-react';
import { Feather } from '@expo/vector-icons';
import * as ImagePicker from 'expo-image-picker';

import { DynamicForm } from '@/components/forms/dynamic-form';
import { getTemplateById } from '@/lib/api/templates';
import { Template } from '@/lib/types/template';
import { RunFormSchema, RunTemplateData } from '@/lib/types/template-run';
import { transformWorkflowToFormSchema, validateFormSchema } from '@/lib/utils/form-schema-transformer';

interface Step1FormData {
  characterImage: string;
  productImage: string;
  script: string;
}

interface Step2FormData extends RunTemplateData {}

interface FormData {
  step1: Step1FormData;
  step2: Step2FormData;
}

type UploadFieldKey = 'characterImage' | 'productImage';

const FALLBACK_PREVIEW =
  'https://images.unsplash.com/photo-1542204165-0198c1e21a3b?auto=format&fit=crop&w=1200&q=80';
const FALLBACK_INSET =
  'https://images.unsplash.com/photo-1524504388940-b1c1722653e1?auto=format&fit=crop&w=640&q=80';

export default function TemplateFormScreen() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const router = useRouter();

  const [currentStep, setCurrentStep] = useState(1);
  const [template, setTemplate] = useState<Template | null>(null);
  const [formSchema, setFormSchema] = useState<RunFormSchema>({ fields: [] });
  const [loading, setLoading] = useState(true);

  const [formData, setFormData] = useState<FormData>({
    step1: {
      characterImage: '',
      productImage: '',
      script: '',
    },
    step2: {},
  });

  const [errors, setErrors] = useState<Record<string, string>>({});
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    loadInitialData();
  }, [id]);

  const loadInitialData = async () => {
    try {
      setLoading(true);
      const templateResponse = await getTemplateById(id);

      if (templateResponse.success && templateResponse.data) {
        setTemplate(templateResponse.data);

        if (templateResponse.data.formSchema) {
          try {
            const rawData =
              typeof templateResponse.data.formSchema === 'string'
                ? JSON.parse(templateResponse.data.formSchema as string)
                : templateResponse.data.formSchema;

            const formConfig = transformWorkflowToFormSchema(rawData);

            if (validateFormSchema(formConfig)) {
              setFormSchema(formConfig);
            }
          } catch (error) {
            console.error('Failed to parse form schema:', error);
          }
        }
      }
    } catch (error) {
      console.error('Failed to load template:', error);
      Alert.alert('Error', 'Failed to load data. Please retry later.');
    } finally {
      setLoading(false);
    }
  };

  const validateStep1 = (): boolean => {
    const newErrors: Record<string, string> = {};

    if (!formData.step1.characterImage) {
      newErrors.characterImage = 'Please upload the character image';
    }

    if (!formData.step1.productImage) {
      newErrors.productImage = 'Please upload the product image';
    }

    if (!formData.step1.script.trim()) {
      newErrors.script = 'Please provide the character script';
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleStep1Next = () => {
    if (validateStep1()) {
      setCurrentStep(2);
    }
  };

  const handleStep2Prev = () => {
    setCurrentStep(1);
  };

  const handleStep2Submit = async () => {
    if (!template) return;

    setIsSubmitting(true);

    try {
      const combinedData = {
        ...formData.step1,
        ...formData.step2,
      };

      console.log('Submitting template payload:', combinedData);

      Alert.alert('Success', 'Template configuration saved.', [
        {
          text: 'OK',
          onPress: () => {
            router.push(`/templates/${id}/run`);
          },
        },
      ]);
    } catch (error) {
      console.error('Submission failed:', error);
      Alert.alert('Error', 'Submission failed. Please retry later.');
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleImagePick = async (field: UploadFieldKey) => {
    try {
      const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();

      if (!permission.granted) {
        Alert.alert(
          'Permission Required',
          'Please allow photo library access in Settings to upload images.',
        );
        return;
      }

      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.Images,
        allowsEditing: true,
        quality: 0.9,
      });

      if (result.canceled || !result.assets || result.assets.length === 0) {
        return;
      }

      const uri = result.assets[0].uri;

      setFormData(prev => ({
        ...prev,
        step1: {
          ...prev.step1,
          [field]: uri,
        },
      }));

      if (errors[field]) {
        setErrors(prev => ({
          ...prev,
          [field]: '',
        }));
      }
    } catch (error) {
      console.error('Failed to pick image:', error);
      Alert.alert('Error', 'Unable to pick image. Please try again later.');
    }
  };

  const renderUploadCard = (
    field: UploadFieldKey,
    label: string,
    description: string,
  ) => {
    const value = formData.step1[field];

    return (
      <View style={styles.uploadItem}>
        <TouchableOpacity
          activeOpacity={0.9}
          onPress={() => handleImagePick(field)}
          style={[
            styles.uploadCard,
            value && styles.uploadCardFilled,
            errors[field] && styles.uploadCardError,
          ]}
        >
          {value ? (
            <Image source={{ uri: value }} style={styles.uploadImage} />
          ) : (
            <>
              <View style={styles.uploadIconWrap}>
                <UploadCloud size={26} color="#D1FF00" strokeWidth={1.4} />
              </View>
              <Text style={styles.uploadLabel}>{label}</Text>
              <Text style={styles.uploadDescription}>{description}</Text>
            </>
          )}
        </TouchableOpacity>
        {errors[field] ? (
          <Text style={styles.inlineError}>{errors[field]}</Text>
        ) : null}
      </View>
    );
  };

  const renderStep1 = () => {
    const heroImage = template?.previewUrl || template?.coverImageUrl || FALLBACK_PREVIEW;
    const insetImage = template?.coverImageUrl || FALLBACK_INSET;

    return (
      <ScrollView
        style={styles.stepScroll}
        contentContainerStyle={styles.step1Content}
        showsVerticalScrollIndicator={false}
      >
        <View style={styles.topBar}>
          <TouchableOpacity
            activeOpacity={0.85}
            onPress={() => router.back()}
            style={styles.backButton}
          >
            <ArrowLeft size={22} color="#FFFFFF" strokeWidth={2.4} />
          </TouchableOpacity>
        </View>

        <Text style={styles.heroTitle}>
          {(template?.title ?? 'Insert your product into an ASMR video').toUpperCase()}
        </Text>
        <Text style={styles.heroSubtitle}>
          {template?.description ||
            'ASMR-Add-On keeps your original image the same while seamlessly adding our uploaded product into the ASMR scene.'}
        </Text>

        <View style={styles.previewStage}>
          <Image source={{ uri: heroImage }} style={styles.previewImage} />
          <View style={styles.previewInset}>
            <Image source={{ uri: insetImage }} style={styles.previewInsetImage} />
          </View>
        </View>

        <View style={styles.uploadRow}>
          {renderUploadCard(
            'characterImage',
            'UPLOAD CHARACTER IMAGE',
            'PNG, JPG or Paste from clipboard',
          )}
          {renderUploadCard(
            'productImage',
            'UPLOAD CHARACTER IMAGE',
            'PNG, JPG or Paste from clipboard',
          )}
        </View>

        <View style={styles.promptField}>
          <TextInput
            style={[styles.promptInput, errors.script && styles.promptInputError]}
            placeholder="What should your character say?"
            placeholderTextColor="rgba(255, 255, 255, 0.5)"
            value={formData.step1.script}
            onChangeText={text => {
              setFormData(prev => ({
                ...prev,
                step1: {
                  ...prev.step1,
                  script: text,
                },
              }));
              if (errors.script) {
                setErrors(prev => ({
                  ...prev,
                  script: '',
                }));
              }
            }}
            multiline
            textAlignVertical="top"
          />
          {errors.script ? <Text style={styles.inlineError}>{errors.script}</Text> : null}
        </View>

        <TouchableOpacity
          style={styles.generateButton}
          activeOpacity={0.88}
          onPress={handleStep1Next}
        >
          <Feather name="star" size={20} color="#050505" />
          <Text style={styles.generateLabel}>Generate Video</Text>
        </TouchableOpacity>
      </ScrollView>
    );
  };

  const renderStep2 = () => (
    <View style={styles.step2Wrapper}>
      <View style={styles.topBar}>
        <TouchableOpacity
          activeOpacity={0.85}
          onPress={handleStep2Prev}
          style={styles.backButton}
        >
          <ArrowLeft size={22} color="#FFFFFF" strokeWidth={2.4} />
        </TouchableOpacity>
        <Text style={styles.stepIndicator}>STEP 2 OF 2</Text>
      </View>

      <Text style={styles.step2Title}>Run Parameters</Text>
      <Text style={styles.step2Subtitle}>
        Fine-tune the details so the ASMR video delivers the mood you expect.
      </Text>

      <View style={styles.step2FormShell}>
        {formSchema.fields.length > 0 ? (
          <DynamicForm
            schema={formSchema}
            initialData={formData.step2}
            onDataChange={data => {
              setFormData(prev => ({
                ...prev,
                step2: data,
              }));
            }}
          />
        ) : (
          <View style={styles.emptyState}>
            <Text style={styles.emptyIcon}>📋</Text>
            <Text style={styles.emptyText}>No extra parameters</Text>
            <Text style={styles.emptyDescription}>
              This template is ready to go—start generating the ASMR experience instantly.
            </Text>
          </View>
        )}
      </View>
    </View>
  );

  const renderBottomActions = () => {
    if (currentStep !== 2) {
      return null;
    }

    return (
      <SafeAreaView edges={['bottom']} style={styles.bottomSafeArea}>
        <View style={styles.bottomActions}>
          <TouchableOpacity
            style={styles.secondaryButton}
            activeOpacity={0.85}
            onPress={handleStep2Prev}
          >
            <Text style={styles.secondaryLabel}>Back</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={styles.submitButton}
            activeOpacity={0.9}
            onPress={handleStep2Submit}
            disabled={isSubmitting}
          >
            {isSubmitting ? (
              <ActivityIndicator color="#050505" />
            ) : (
              <>
                <Feather name="zap" size={18} color="#050505" />
                <Text style={styles.submitLabel}>Generate Video</Text>
              </>
            )}
          </TouchableOpacity>
        </View>
      </SafeAreaView>
    );
  };

  if (loading) {
    return (
      <View style={styles.loadingCanvas}>
        <SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color="#D1FF00" />
            <Text style={styles.loadingText}>Loading...</Text>
          </View>
        </SafeAreaView>
      </View>
    );
  }

  return (
    <View style={styles.canvas}>
      <SafeAreaView style={styles.safeArea} edges={['top', 'left', 'right']}>
        {currentStep === 1 ? renderStep1() : renderStep2()}
      </SafeAreaView>
      {renderBottomActions()}
    </View>
  );
}

const styles = StyleSheet.create({
  canvas: {
    flex: 1,
    backgroundColor: '#050505',
  },
  safeArea: {
    flex: 1,
  },
  loadingCanvas: {
    flex: 1,
    backgroundColor: '#050505',
  },
  loadingContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  loadingText: {
    marginTop: 16,
    fontSize: 16,
    color: 'rgba(255, 255, 255, 0.7)',
    letterSpacing: 0.3,
  },
  stepScroll: {
    flex: 1,
  },
  step1Content: {
    paddingHorizontal: 24,
    paddingBottom: 40,
  },
  topBar: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 28,
  },
  backButton: {
    width: 48,
    height: 48,
    borderRadius: 18,
    borderWidth: 1,
    borderColor: 'rgba(255, 255, 255, 0.1)',
    backgroundColor: 'rgba(18, 18, 18, 0.78)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  stepIndicator: {
    flex: 1,
    textAlign: 'right',
    fontSize: 13,
    letterSpacing: 2,
    color: 'rgba(255, 255, 255, 0.5)',
  },
  heroTitle: {
    fontSize: 26,
    lineHeight: 32,
    fontWeight: '700',
    color: '#FFFFFF',
    letterSpacing: 0.8,
    textTransform: 'uppercase',
    marginBottom: 16,
  },
  heroSubtitle: {
    fontSize: 14,
    lineHeight: 20,
    color: 'rgba(255, 255, 255, 0.68)',
    marginBottom: 24,
  },
  previewStage: {
    borderRadius: 32,
    overflow: 'hidden',
    backgroundColor: '#111318',
    marginBottom: 28,
  },
  previewImage: {
    width: '100%',
    height: 220,
  },
  previewInset: {
    position: 'absolute',
    bottom: 18,
    left: 18,
    width: 74,
    height: 74,
    borderRadius: 24,
    borderWidth: 2,
    borderColor: '#050505',
    backgroundColor: '#050505',
    overflow: 'hidden',
  },
  previewInsetImage: {
    width: '100%',
    height: '100%',
  },
  uploadRow: {
    flexDirection: 'row',
    gap: 18,
    marginBottom: 24,
  },
  uploadItem: {
    flex: 1,
  },
  uploadCard: {
    borderRadius: 28,
    borderWidth: 1,
    borderColor: 'rgba(255, 255, 255, 0.08)',
    backgroundColor: 'rgba(17, 19, 24, 0.95)',
    paddingHorizontal: 20,
    paddingVertical: 28,
    alignItems: 'center',
    justifyContent: 'center',
    minHeight: 188,
    overflow: 'hidden',
  },
  uploadCardFilled: {
    paddingHorizontal: 0,
    paddingVertical: 0,
  },
  uploadCardError: {
    borderColor: '#FF6B6B',
  },
  uploadIconWrap: {
    width: 60,
    height: 60,
    borderRadius: 22,
    backgroundColor: 'rgba(209, 255, 0, 0.12)',
    alignItems: 'center',
    justifyContent: 'center',
    marginBottom: 16,
  },
  uploadLabel: {
    fontSize: 14,
    fontWeight: '700',
    letterSpacing: 0.6,
    color: '#FFFFFF',
    textAlign: 'center',
    textTransform: 'uppercase',
    marginBottom: 6,
  },
  uploadDescription: {
    fontSize: 12,
    lineHeight: 16,
    color: 'rgba(255, 255, 255, 0.55)',
    textAlign: 'center',
  },
  uploadImage: {
    width: '100%',
    height: '100%',
    resizeMode: 'cover',
  },
  promptField: {
    marginBottom: 18,
  },
  promptInput: {
    borderRadius: 28,
    borderWidth: 1,
    borderColor: 'rgba(255, 255, 255, 0.08)',
    backgroundColor: 'rgba(17, 19, 24, 0.95)',
    minHeight: 140,
    paddingHorizontal: 22,
    paddingVertical: 22,
    fontSize: 15,
    lineHeight: 22,
    color: '#FFFFFF',
  },
  promptInputError: {
    borderColor: '#FF6B6B',
  },
  inlineError: {
    marginTop: 8,
    fontSize: 12,
    color: '#FF6B6B',
    letterSpacing: 0.2,
  },
  generateButton: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    height: 58,
    borderRadius: 30,
    backgroundColor: '#D1FF00',
    gap: 10,
  },
  generateLabel: {
    fontSize: 17,
    fontWeight: '700',
    letterSpacing: 0.4,
    color: '#050505',
  },
  step2Wrapper: {
    flex: 1,
    paddingHorizontal: 24,
    paddingBottom: 24,
  },
  step2Title: {
    fontSize: 22,
    fontWeight: '700',
    color: '#FFFFFF',
    letterSpacing: 0.6,
    marginBottom: 10,
  },
  step2Subtitle: {
    fontSize: 13,
    lineHeight: 18,
    color: 'rgba(255, 255, 255, 0.6)',
    marginBottom: 20,
  },
  step2FormShell: {
    flex: 1,
    borderRadius: 32,
    backgroundColor: 'rgba(17, 19, 24, 0.78)',
    overflow: 'hidden',
  },
  emptyState: {
    flex: 1,
    paddingHorizontal: 32,
    alignItems: 'center',
    justifyContent: 'center',
  },
  emptyIcon: {
    fontSize: 48,
    marginBottom: 16,
    color: '#FFFFFF',
  },
  emptyText: {
    fontSize: 18,
    fontWeight: '600',
    color: '#FFFFFF',
    marginBottom: 8,
  },
  emptyDescription: {
    fontSize: 14,
    lineHeight: 20,
    color: 'rgba(255, 255, 255, 0.6)',
    textAlign: 'center',
  },
  bottomSafeArea: {
    backgroundColor: '#050505',
  },
  bottomActions: {
    flexDirection: 'row',
    gap: 16,
    paddingHorizontal: 24,
    paddingTop: 12,
    paddingBottom: 24,
    borderTopWidth: 1,
    borderTopColor: 'rgba(255, 255, 255, 0.08)',
  },
  secondaryButton: {
    flex: 1,
    height: 56,
    borderRadius: 28,
    borderWidth: 1,
    borderColor: 'rgba(255, 255, 255, 0.2)',
    alignItems: 'center',
    justifyContent: 'center',
  },
  secondaryLabel: {
    fontSize: 15,
    fontWeight: '600',
    color: 'rgba(255, 255, 255, 0.78)',
    letterSpacing: 0.2,
  },
  submitButton: {
    flex: 1.6,
    height: 56,
    borderRadius: 28,
    backgroundColor: '#D1FF00',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 10,
  },
  submitLabel: {
    fontSize: 16,
    fontWeight: '700',
    color: '#050505',
    letterSpacing: 0.3,
  },
});
