refactor this code. This is for an expo mobile app. Make sure its dynamic. Split the Code and the styling.
// App.js
import React, { useState, useEffect, useRef } from 'react';
import {
  View,
  Text,
  StyleSheet,
  ScrollView,
  TextInput,
  TouchableOpacity,
  Modal,
  Image,
  Button,
  Alert,
} from 'react-native';
import SignatureCanvas from 'react-native-signature-canvas';
import { Audio } from 'expo-av';
import { Camera } from 'expo-camera';
import * as Print from 'expo-print';
import * as Sharing from 'expo-sharing';

export default function App() {
  // State variables for names
  const [name1, setName1] = useState('');
  const [name2, setName2] = useState('');

  // State variables for signatures
  const [signature1, setSignature1] = useState(null);
  const [signature2, setSignature2] = useState(null);
  const [modalVisible, setModalVisible] = useState(false);
  const [currentSignature, setCurrentSignature] = useState(null); // 'signature1' or 'signature2'

  // State variables for audio recording
  const [recording1, setRecording1] = useState(null);
  const [recording2, setRecording2] = useState(null);
  const [sound1, setSound1] = useState(null);
  const [sound2, setSound2] = useState(null);

  // State variables for permissions
  const [hasCameraPermission, setHasCameraPermission] = useState(null);
  const [hasAudioPermission, setHasAudioPermission] = useState(null);

  // Reference to the camera
  const cameraRef = useRef(null);

  // State variables for photos
  const [photoUri1, setPhotoUri1] = useState(null);
  const [photoUri2, setPhotoUri2] = useState(null);

  // State variables for camera modal
  const [isCameraVisible, setIsCameraVisible] = useState(false);
  const [currentPhotoSection, setCurrentPhotoSection] = useState(null); // 'photo1' or 'photo2'

  // Signature pad style for react-native-signature-canvas
  const signatureStyle = `.m-signature-pad--footer
    .button {
      background-color: #000000;
      color: #FFFFFF;
    } 
    body,html {
      width: 100%; height: 100%;
    } 
    .m-signature-pad {
      box-shadow: none; border: none;
    }
    .m-signature-pad--body {
      border: none;
    }
  `;

  const legalText = `
# Legal Agreement

Please read the following terms and conditions carefully before using this application...

* Term 1
* Term 2
* Term 3

By using this app, you agree to the above terms.
`;

  // Request permissions on component mount
  useEffect(() => {
    (async () => {
      const cameraStatus = await Camera.requestCameraPermissionsAsync();
      setHasCameraPermission(cameraStatus.status === 'granted');

      const audioStatus = await Audio.requestPermissionsAsync();
      setHasAudioPermission(audioStatus.status === 'granted');
    })();
  }, []);

  // Handle signature capture
  const handleSignature = (signature) => {
    if (currentSignature === 'signature1') {
      setSignature1(signature);
    } else if (currentSignature === 'signature2') {
      setSignature2(signature);
    }
    setModalVisible(false);
  };

  // Handle empty signature
  const handleEmpty = () => {
    Alert.alert('Signature Required', 'Please provide a signature.');
  };

  // Start recording audio
  const startRecording = async (section) => {
    try {
      if (!hasAudioPermission) {
        Alert.alert('Permission Denied', 'No access to microphone.');
        return;
      }

      console.log('Requesting audio permissions...');
      await Audio.setAudioModeAsync({
        allowsRecordingIOS: true,
        playsInSilentModeIOS: true,
      });

      console.log('Starting recording...');
      const { recording } = await Audio.Recording.createAsync(
        Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
      );
      if (section === 1) {
        setRecording1(recording);
      } else if (section === 2) {
        setRecording2(recording);
      }
      console.log('Recording started');
    } catch (err) {
      console.error('Failed to start recording', err);
      Alert.alert('Error', 'Failed to start recording.');
    }
  };

  // Stop recording audio
  const stopRecording = async (section) => {
    try {
      if (section === 1 && recording1) {
        console.log('Stopping recording...');
        await recording1.stopAndUnloadAsync();
        const uri = recording1.getURI();
        console.log('Recording stored at', uri);
        setRecording1(null);
        Alert.alert('Recording Stopped', `Recording stored at ${uri}`);
      } else if (section === 2 && recording2) {
        console.log('Stopping recording...');
        await recording2.stopAndUnloadAsync();
        const uri = recording2.getURI();
        console.log('Recording stored at', uri);
        setRecording2(null);
        Alert.alert('Recording Stopped', `Recording stored at ${uri}`);
      }
    } catch (error) {
      console.error('Failed to stop recording', error);
      Alert.alert('Error', 'Failed to stop recording.');
    }
  };

  // Take picture using camera
  const takePicture = async () => {
    try {
      if (cameraRef.current) {
        const photo = await cameraRef.current.takePictureAsync({
          base64: false, // Set to true if embedding base64 images
        });
        if (currentPhotoSection === 'photo1') {
          setPhotoUri1(photo.uri);
        } else if (currentPhotoSection === 'photo2') {
          setPhotoUri2(photo.uri);
        }
        setIsCameraVisible(false);
        Alert.alert('Photo Captured', 'Photo has been successfully captured.');
      }
    } catch (error) {
      console.error('Error capturing photo:', error);
      Alert.alert('Error', 'An error occurred while capturing the photo.');
    }
  };

  // Generate and share PDF
  const generateAndSharePDF = async () => {
    // Prepare the HTML content
    const htmlContent = `
      <html>
        <head>
          <meta charset="utf-8">
          <title>Legal Agreement</title>
          <style>
            body { font-family: Arial, sans-serif; padding: 20px; }
            h1 { text-align: center; }
            .section { margin-bottom: 20px; }
            .signature { margin-top: 10px; }
            img { max-width: 100%; height: auto; margin-top: 10px; }
          </style>
        </head>
        <body>
          <h1>Legal Agreement</h1>
          <div class="section">
            ${legalText.replace(/\n/g, '<br />')}
          </div>
          <div class="section">
            <h2>Names</h2>
            <p><strong>Name 1:</strong> ${name1 || 'N/A'}</p>
            <p><strong>Name 2:</strong> ${name2 || 'N/A'}</p>
          </div>
          <div class="section">
            <h2>Signatures</h2>
            <p><strong>Signature 1:</strong></p>
            ${
              signature1
                ? `<img src="${signature1}" alt="Signature 1" />`
                : '<p>No signature provided.</p>'
            }
            <p><strong>Signature 2:</strong></p>
            ${
              signature2
                ? `<img src="${signature2}" alt="Signature 2" />`
                : '<p>No signature provided.</p>'
            }
          </div>
          <div class="section">
            <h2>Captured Photos</h2>
            <p><strong>Photo 1:</strong></p>
            ${
              photoUri1
                ? `<img src="${photoUri1}" alt="Captured Photo 1" />`
                : '<p>No photo captured.</p>'
            }
            <p><strong>Photo 2:</strong></p>
            ${
              photoUri2
                ? `<img src="${photoUri2}" alt="Captured Photo 2" />`
                : '<p>No photo captured.</p>'
            }
            <!-- Audio recordings can be linked or embedded here if needed -->
          </div>
        </body>
      </html>
    `;

    try {
      // Validate form before generating PDF
      if (!validateForm()) return;

      // Generate PDF from HTML
      const { uri } = await Print.printToFileAsync({
        html: htmlContent,
        base64: false,
      });

      console.log('PDF generated at:', uri);

      // Check if sharing is available
      if (!(await Sharing.isAvailableAsync())) {
        Alert.alert('PDF Generated', `PDF is available at: ${uri}`);
        return;
      }

      // Share the PDF
      await Sharing.shareAsync(uri);
    } catch (error) {
      console.error('Error generating or sharing PDF:', error);
      Alert.alert('Error', 'An error occurred while generating the PDF.');
    }
  };

  // Form validation
  const validateForm = () => {
    if (!name1.trim() || !name2.trim()) {
      Alert.alert('Validation Error', 'Please enter both names.');
      return false;
    }
    if (!signature1 || !signature2) {
      Alert.alert('Validation Error', 'Please provide both signatures.');
      return false;
    }
    return true;
  };

  return (
    <View style={styles.container}>
      <Text style={styles.header}>Legal Agreement</Text>

      {/* Scrollable Legal Text */}
      <ScrollView style={styles.legalTextContainer}>
        <Text style={styles.legalText}>{legalText}</Text>
      </ScrollView>

      {/* Name Inputs */}
      <View style={styles.inputSection}>
        <View style={styles.inputContainer}>
          <Text style={styles.label}>Name 1:</Text>
          <TextInput
            style={styles.input}
            placeholder="Enter your name"
            onChangeText={(text) => setName1(text)}
            value={name1}
          />
        </View>

        <View style={styles.inputContainer}>
          <Text style={styles.label}>Name 2:</Text>
          <TextInput
            style={styles.input}
            placeholder="Enter your name"
            onChangeText={(text) => setName2(text)}
            value={name2}
          />
        </View>
      </View>

      {/* Signature Sections */}
      <View style={styles.signatureContainer}>
        {/* Signature 1 */}
        <View style={styles.signatureSection}>
          <Text style={styles.label}>Signature 1:</Text>
          {signature1 ? (
            <Image
              resizeMode="contain"
              style={styles.signatureImage}
              source={{ uri: signature1 }}
            />
          ) : (
            <View style={styles.signatureBox}>
              <Text>No signature</Text>
            </View>
          )}
          <TouchableOpacity
            style={styles.signatureButton}
            onPress={() => {
              setCurrentSignature('signature1');
              setModalVisible(true);
            }}
          >
            <Text style={styles.buttonText}>Provide Signature</Text>
          </TouchableOpacity>

          {/* Voice Recording and Camera Buttons */}
          <View style={styles.buttonRow}>
            <TouchableOpacity
              style={styles.recordButton}
              onPress={() => {
                if (!recording1) {
                  startRecording(1);
                } else {
                  stopRecording(1);
                }
              }}
            >
              <Text style={styles.buttonText}>
                {recording1 ? 'Stop Recording' : 'Record Voice'}
              </Text>
            </TouchableOpacity>

            <TouchableOpacity
              style={styles.cameraButton}
              onPress={() => {
                setCurrentPhotoSection('photo1');
                setIsCameraVisible(true);
              }}
            >
              <Text style={styles.buttonText}>Capture Photo</Text>
            </TouchableOpacity>
          </View>

          {/* Display Captured Photo */}
          {photoUri1 && (
            <Image
              source={{ uri: photoUri1 }}
              style={styles.capturedPhoto}
            />
          )}
        </View>

        {/* Signature 2 */}
        <View style={styles.signatureSection}>
          <Text style={styles.label}>Signature 2:</Text>
          {signature2 ? (
            <Image
              resizeMode="contain"
              style={styles.signatureImage}
              source={{ uri: signature2 }}
            />
          ) : (
            <View style={styles.signatureBox}>
              <Text>No signature</Text>
            </View>
          )}
          <TouchableOpacity
            style={styles.signatureButton}
            onPress={() => {
              setCurrentSignature('signature2');
              setModalVisible(true);
            }}
          >
            <Text style={styles.buttonText}>Provide Signature</Text>
          </TouchableOpacity>

          {/* Voice Recording and Camera Buttons */}
          <View style={styles.buttonRow}>
            <TouchableOpacity
              style={styles.recordButton}
              onPress={() => {
                if (!recording2) {
                  startRecording(2);
                } else {
                  stopRecording(2);
                }
              }}
            >
              <Text style={styles.buttonText}>
                {recording2 ? 'Stop Recording' : 'Record Voice'}
              </Text>
            </TouchableOpacity>

            <TouchableOpacity
              style={styles.cameraButton}
              onPress={() => {
                setCurrentPhotoSection('photo2');
                setIsCameraVisible(true);
              }}
            >
              <Text style={styles.buttonText}>Capture Photo</Text>
            </TouchableOpacity>
          </View>

          {/* Display Captured Photo */}
          {photoUri2 && (
            <Image
              source={{ uri: photoUri2 }}
              style={styles.capturedPhoto}
            />
          )}
        </View>
      </View>

      {/* Download PDF Button */}
      <TouchableOpacity style={styles.downloadButton} onPress={generateAndSharePDF}>
        <Text style={styles.downloadButtonText}>Download PDF</Text>
      </TouchableOpacity>

      {/* Signature Modal */}
      <Modal visible={modalVisible} animationType="slide">
        <SignatureCanvas
          onOK={handleSignature}
          onEmpty={handleEmpty}
          descriptionText="Sign"
          clearText="Clear"
          confirmText="Save"
          webStyle={signatureStyle}
        />
        <Button title="Cancel" onPress={() => setModalVisible(false)} />
      </Modal>

      {/* Camera Modal */}
      <Modal visible={isCameraVisible} animationType="slide">
        <View style={styles.cameraModalContainer}>
          <Camera
            ref={cameraRef}
            style={styles.cameraStyle}
            type={Camera.Constants.Type.back}
          >
            <View style={styles.cameraButtonContainer}>
              <TouchableOpacity
                style={styles.captureButton}
                onPress={takePicture}
              >
                <Text style={styles.cameraButtonText}>Capture</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={styles.captureButton}
                onPress={() => setIsCameraVisible(false)}
              >
                <Text style={styles.cameraButtonText}>Cancel</Text>
              </TouchableOpacity>
            </View>
          </Camera>
        </View>
      </Modal>
    </View>
  );
}

// Styles
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  header: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginVertical: 10,
  },
  legalTextContainer: {
    flex: 2,
    marginVertical: 10,
    borderWidth: 1,
    borderColor: '#ccc',
    padding: 10,
  },
  legalText: {
    fontSize: 16,
    lineHeight: 24,
  },
  inputSection: {
    marginVertical: 10,
  },
  inputContainer: {
    marginBottom: 10,
  },
  label: {
    fontSize: 16,
    marginBottom: 4,
    fontWeight: '600',
  },
  input: {
    borderWidth: 1,
    borderColor: '#777',
    padding: 8,
    borderRadius: 4,
  },
  signatureContainer: {
    marginVertical: 10,
  },
  signatureSection: {
    marginBottom: 20,
  },
  signatureBox: {
    width: '100%',
    height: 100,
    borderWidth: 1,
    borderColor: '#777',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 10,
  },
  signatureImage: {
    width: '100%',
    height: 100,
    borderWidth: 1,
    borderColor: '#777',
    marginBottom: 10,
  },
  signatureButton: {
    backgroundColor: '#4682B4',
    padding: 10,
    borderRadius: 4,
    alignItems: 'center',
    marginBottom: 10,
  },
  buttonRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  recordButton: {
    backgroundColor: '#32CD32',
    padding: 10,
    borderRadius: 4,
    alignItems: 'center',
    flex: 0.48,
  },
  cameraButton: {
    backgroundColor: '#FF8C00',
    padding: 10,
    borderRadius: 4,
    alignItems: 'center',
    flex: 0.48,
  },
  buttonText: {
    color: '#fff',
    fontWeight: 'bold',
  },
  downloadButton: {
    backgroundColor: '#4CAF50',
    padding: 15,
    borderRadius: 8,
    alignItems: 'center',
    marginTop: 20,
  },
  downloadButtonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
  capturedPhoto: {
    width: '100%',
    height: 200,
    borderWidth: 1,
    borderColor: '#777',
    marginTop: 10,
  },
  photoPreviewContainer: {
    marginVertical: 10,
    alignItems: 'center',
  },
  cameraModalContainer: {
    flex: 1,
    backgroundColor: '#000',
  },
  cameraStyle: {
    flex: 1,
  },
  cameraButtonContainer: {
    flex: 1,
    backgroundColor: 'transparent',
    flexDirection: 'row',
    margin: 20,
    alignItems: 'flex-end',
    justifyContent: 'space-between',
  },
  captureButton: {
    backgroundColor: '#fff',
    padding: 15,
    borderRadius: 5,
    alignSelf: 'center',
  },
  cameraButtonText: {
    fontSize: 16,
    fontWeight: 'bold',
    color: '#000',
  },
});