import { FastField, Field, Formik, FormikHelpers } from 'formik';
import mapValues from 'lodash/mapValues';
import React, { forwardRef, useEffect, useMemo, useState } from 'react';
import {
    Dimensions,
    SectionList,
    SectionListData,
    SectionListRenderItemInfo,
    StyleSheet,
    Text,
    TouchableOpacity,
    View
} from 'react-native';
import * as Progress from 'react-native-progress';
import Toast from 'react-native-toast-message';
import * as yup from 'yup';

// Custom Components (assuming their props from usage)
import Colors from '../../constants/colors';
import { FormikActions, FormikDocumentPicker, FormikQuestionAnswers, FormikTextInput } from '../formikComponents';

const { width } = Dimensions.get('window');

// --- Type Definitions ---

interface Question {
  questionId: string | number;
  question: string;
  group_title: string;
  weightage: string | number;
  // Add any other properties a question might have
}

interface ActionPlan {
  question_id: string | number;
  body: string;
  close_immediately: string; // "0" or "1"
  field_target_date: string | Date;
  field_critical_to_safety: string;
  field_issue_type: string;
  field_responsible_person: string;
}

interface FormValues {
  [key: string]: string | ActionPlan | undefined;
}

interface GroupScoreData {
  totalGroupWeightage: number;
  groupScores: { [key: string]: number };
  groupNas: { [key: string]: number };
  groupTotalScore: number;
}

interface Score {
  totalScore: number;
  groupScoreData: { [groupTitle: string]: GroupScoreData };
}

interface DraftData {
  formId: string;
  selectedEntity: string;
  draftValues: FormValues;
  score: Score;
}

interface QuestionsFormProps {
  userEmails?: any[]; // Specify a more concrete type if available
  isActionplan: boolean;
  data: Question[];
  radioButtonOptions: any[]; // Specify a more concrete type if available
  submitAnswer: (values: FormValues) => void;
  navigation: { navigate: (screen: string) => void };
  clearFilter: () => void;
  isUnAnswered: boolean;
  formId: string;
  draftAnswer: (values: FormValues, formId: string, score: Score) => void;
  draftAnswerData: DraftData[];
  removeSubmittedFormDraft: (formId: string, selectedEntity: string) => void;
  selectedEntity: string;
  calculateProgress: (progress: number) => void;
  // selectedGroup and triggerActionPlanFilter seem unused in the provided logic but are kept for prop compatibility
  selectedGroup?: any;
  triggerActionPlanFilter?: () => void;
}

// --- Helper Functions (moved outside the component for clarity) ---

const groupBy = <T,>(array: T[], key: keyof T): { [key: string]: T[] } => {
  return array.reduce((result, currentItem) => {
    const groupKey = String(currentItem[key]);
    (result[groupKey] = result[groupKey] || []).push(currentItem);
    return result;
  }, {} as { [key: string]: T[] });
};

// --- Validation Schema ---

const questionsFormSchema = yup.lazy((obj: object) =>
  yup.object(
    mapValues(obj, (value, key) => {
      if (key.endsWith('_answer')) {
        return yup.string().required('Answer is required').min(1);
      }
      if (key.endsWith('_observation')) {
        const answerKey = key.replace('_observation', '_answer');
        return yup.string().when(answerKey, {
          is: (val: string) => ['0', '1', 'no'].includes(val),
          then: (schema: yup.StringSchema) => schema.required('Observation is required'),
          otherwise: (schema: yup.StringSchema) => schema.nullable(),
        });
      }
      if (key.endsWith('_actions')) {
        const answerKey = key.replace('_actions', '_answer');
        return yup.object().when(answerKey, {
          is: (val: string) => ['0', '1', 'no'].includes(val),
          then: (schema: yup.ObjectSchema<any>) =>
            yup.object().shape({
              body: yup.string().required('Corrective Action is required'),
              field_critical_to_safety: yup.string().required('Critical to Safety is required'),
              close_immediately: yup.string().required('Close Immediately is required'),
              field_responsible_person: yup.string().when('close_immediately', {
                is: '0',
                then: (s: yup.StringSchema) => s.required('Responsible Person is required'),
                otherwise: (s: yup.StringSchema) => s.nullable(),
              }),
              field_target_date: yup.string().when('close_immediately', {
                is: '0',
                then: (s: yup.StringSchema) => s.required('Target Date is required'),
                otherwise: (s: yup.StringSchema) => s.nullable(),
              }),
            }),
          otherwise: (schema: yup.ObjectSchema<any>) => schema.nullable(),
        });
      }
      return yup.mixed().nullable();
    }) as yup.ObjectShape
  )
);


// --- Component ---

export const QuestionsForm: React.ForwardRefRenderFunction<SectionList, QuestionsFormProps> = (
  {
    data,
    formId,
    selectedEntity,
    draftAnswerData,
    draftAnswer,
    submitAnswer,
    removeSubmittedFormDraft,
    navigation,
    clearFilter,
    calculateProgress,
    isActionplan,
    isUnAnswered,
    radioButtonOptions,
    userEmails,
  },
  ref
) => {
  // Memoize initial values and draft data lookup to prevent recalculation on every render
  const draftData = useMemo(
    () => draftAnswerData.find(item => item.formId === formId && item.selectedEntity === selectedEntity),
    [draftAnswerData, formId, selectedEntity]
  );

  const initialValues = useMemo<FormValues>(() => {
    const defaultActionPlan = (questionId: string | number): ActionPlan => ({
      question_id: questionId,
      body: '',
      close_immediately: '0',
      field_target_date: '',
      field_critical_to_safety: '',
      field_issue_type: '',
      field_responsible_person: '',
    });

    return data.reduce((acc, item) => {
      const { questionId } = item;
      const draftValues = draftData?.draftValues;

      acc[`${questionId}_observation`] = draftValues?.[`${questionId}_observation`] || '';
      acc[`${questionId}_answer`] = draftValues?.[`${questionId}_answer`] || '';
      acc[`${questionId}_uri`] = draftValues?.[`${questionId}_uri`] || '';
      acc[`${questionId}_actions`] = draftValues?.[`${questionId}_actions`] || defaultActionPlan(questionId);
      
      return acc;
    }, {} as FormValues);
  }, [data, draftData]);

  // State Management with types
  const [score, setScore] = useState<Score>(draftData?.score || { totalScore: 0, groupScoreData: {} });

  // Memoize data grouping for performance
  const groupedQuestions = useMemo(() => groupBy(data, 'group_title'), [data]);
  
  useEffect(() => {
    calculateProgress(score.totalScore);
  }, [score, calculateProgress]);

  const handleSubmitForm = (values: FormValues, { setSubmitting }: FormikHelpers<FormValues>) => {
    removeSubmittedFormDraft(formId, selectedEntity);
    submitAnswer(values);
    navigation.navigate('Home');
    setSubmitting(false);
    Toast.show({ type: 'success', text1: 'Form Submitted Successfully' });
  };

  return (
    <Formik
      key="questionsForm"
      initialValues={initialValues}
      validationSchema={questionsFormSchema}
      onSubmit={handleSubmitForm}
      validateOnChange={false}
      validateOnBlur={true}
      enableReinitialize // Important for when draft data loads
    >
      {({ handleSubmit, isSubmitting, values, setFieldValue, errors, touched }) => {
        // This effect handles saving a draft when the component unmounts
        useEffect(() => {
          return () => {
            draftAnswer(values, formId, score);
          };
        }, [values, formId, score, draftAnswer]);

        // --- Scoring Logic (Corrected) ---
        const calculateScore = (questionId: string | number, answer: string, weightage: number | string) => {
          setScore(prevScore => {
            const newScore: Score = JSON.parse(JSON.stringify(prevScore));
            let obtainedPoints = 0;
            let totalPoints = 0;
            
            Object.keys(groupedQuestions).forEach(gTitle => {
              if (!newScore.groupScoreData[gTitle]) {
                newScore.groupScoreData[gTitle] = {
                  groupScores: {},
                  groupNas: {},
                  totalGroupWeightage: 0,
                  groupTotalScore: 0,
                };
              }
              const groupData = newScore.groupScoreData[gTitle];
              let totalGroupWeightage = 0;

              groupedQuestions[gTitle].forEach(q => {
                totalGroupWeightage += Number(q.weightage);
                if (q.questionId === questionId) {
                  delete groupData.groupScores[questionId];
                  delete groupData.groupNas[questionId];
                  
                  if (answer === 'no' || answer === '0') groupData.groupScores[questionId] = 0;
                  else if (answer === '1') groupData.groupScores[questionId] = Number(weightage) / 2;
                  else if (answer === 'yes' || answer === '2') groupData.groupScores[questionId] = Number(weightage);
                  else if (answer === 'na') groupData.groupNas[questionId] = Number(weightage);
                }
              });

              const groupTotalScore = Object.values(groupData.groupScores).reduce((sum, s) => sum + s, 0);
              const totalNas = Object.values(groupData.groupNas).reduce((sum, s) => sum + s, 0);
              
              const effectiveWeightage = totalGroupWeightage - totalNas;
              obtainedPoints += groupTotalScore;
              totalPoints += effectiveWeightage > 0 ? effectiveWeightage : 0;

              groupData.groupTotalScore = groupTotalScore;
              groupData.totalGroupWeightage = effectiveWeightage;
            });

            newScore.totalScore = totalPoints > 0 ? (obtainedPoints / totalPoints) * 100 : 0;
            return newScore;
          });
        };

        // --- Render Logic ---
        const renderItem = ({ item }: SectionListRenderItemInfo<Question>) => {
          const answerValue = values[`${item.questionId}_answer`] as string;
          let isVisible = true; // Default to visible

          if (isUnAnswered) {
             isVisible = !answerValue;
          }
          if (isActionplan) {
            isVisible = ['0', '1', 'no'].includes(answerValue);
          }

          if (!isVisible) return null;

          // Background color logic
          const answerStyle = (() => {
            switch (answerValue) {
              case '0':
              case 'no':
                return { backgroundColor: Colors.color_00, textColor: Colors.colorWhite, answerText: answerValue === 'no' ? 'NO' : '00' };
              case '1':
                return { backgroundColor: Colors.color_01, textColor: Colors.colorWhite, answerText: '01' };
              case '2':
              case 'yes':
                return { backgroundColor: Colors.color_02, textColor: Colors.colorWhite, answerText: answerValue === 'yes' ? 'YES' : '02' };
              case 'na':
                return { backgroundColor: Colors.color_NA, textColor: Colors.textColor, answerText: 'NA' };
              default:
                return { backgroundColor: Colors.colorWhite, textColor: Colors.textColor, answerText: '' };
            }
          })();

          return (
            <View key={String(item.questionId)} style={styles.outer}>
              <View style={[styles.questionContainer, { backgroundColor: answerStyle.backgroundColor }]}>
                {/* Question Text */}
                <Text style={{ padding: 5, color: answerStyle.textColor, fontSize: 14 }}>{item.question}</Text>
                
                {/* Answers and Score */}
                <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
                  <FastField
                    name={`${item.questionId}_answer`}
                    component={FormikQuestionAnswers}
                    radioButtonOptions={radioButtonOptions}
                    setFieldValue={(name: string, value: string) => {
                      calculateScore(item.questionId, value, item.weightage);
                      setFieldValue(name, value);
                      if (!['0', '1', 'no'].includes(value)) {
                         setFieldValue(`${item.questionId}_actions`, undefined) // Clear actions
                      }
                    }}
                  />
                  {answerStyle.answerText && (
                    <View style={styles.answerValue}>
                      <Text style={[styles.answerText, { color: answerStyle.backgroundColor }]}>{answerStyle.answerText}</Text>
                    </View>
                  )}
                </View>
              </View>

              {/* Observation and Attachment */}
              <View style={{ marginHorizontal: 2, marginVertical: 2, padding: 1, flexDirection: 'row', alignItems: 'center' }}>
                 <Field
                    name={`${item.questionId}_observation`}
                    component={FormikTextInput}
                    placeholder="Observation"
                    style={{
                      borderColor: touched[`${item.questionId}_observation`] && errors[`${item.questionId}_observation`] ? 'red' : '#ECECEC',
                      backgroundColor: values[`${item.questionId}_observation`] ? answerStyle.backgroundColor : '#ECECEC',
                      color: answerStyle.textColor,
                      ...styles.observationInput
                    }}
                 />
                 <Field
                    name={`${item.questionId}_uri`}
                    component={FormikDocumentPicker}
                    setFieldValue={setFieldValue}
                    backgroundColor={answerStyle.backgroundColor}
                    textColor={answerStyle.textColor}
                    type="image"
                 />
              </View>
              {touched[`${item.questionId}_answer`] && errors[`${item.questionId}_answer`] && <Text style={styles.errorTextStyle}>{errors[`${item.questionId}_answer`] as string}</Text>}

              {/* Action Plan */}
              {isActionplan && ['0', '1', 'no'].includes(answerValue) && (
                 <FastField
                    name={`${item.questionId}_actions`}
                    component={FormikActions}
                    userEmails={userEmails}
                    validationErrors={touched[`${item.questionId}_actions`] && errors[`${item.questionId}_actions`] ? errors[`${item.questionId}_actions`] : {}}
                 />
              )}
            </View>
          );
        };

        const renderSectionHeader = ({ section }: { section: SectionListData<Question> }) => {
          const { title } = section;
          const groupScoreInfo = score.groupScoreData[title];

          // Simplified visibility logic for headers
          return (
            <View style={styles.sectionHeaderContainer}>
                <View style={styles.sectionHeaderTitleRow}>
                    <Text style={styles.sectionHeaderTitle}>{title}</Text>
                    <View style={styles.headerLine} />
                </View>
                {groupScoreInfo && (
                  <Text style={styles.groupScoreText}>
                    {`${groupScoreInfo.groupTotalScore.toFixed(1)} / ${groupScoreInfo.totalGroupWeightage.toFixed(1)}`}
                  </Text>
                )}
            </View>
          );
        };
        
        const sectionListData = useMemo(() => 
          Object.keys(groupedQuestions).map(title => ({
            title,
            data: groupedQuestions[title]
          })), [groupedQuestions]);
        
        const progressValue = score.totalScore > 0 ? score.totalScore / 100 : 0;

        return (
          <>
            <SectionList
              ref={ref}
              sections={sectionListData}
              renderItem={renderItem}
              renderSectionHeader={renderSectionHeader}
              keyExtractor={(item) => item.questionId.toString()}
              contentContainerStyle={{ paddingBottom: 100 }} // Ensure space for bottom buttons
              stickySectionHeadersEnabled
            />

            {/* Bottom Controls */}
            <View style={styles.bottomBar}>
              <Progress.Circle
                unfilledColor={Colors.appBackgroundColor}
                color={Colors.buttonColor}
                showsText
                size={70}
                progress={progressValue}
                formatText={() => `${score.totalScore.toFixed(0)}%`}
                thickness={5}
              />
              <View style={styles.buttonContainer}>
                <TouchableOpacity
                  style={[styles.buttonBase, styles.saveButton]}
                  onPress={() => {
                    draftAnswer(values, formId, score);
                    Toast.show({ type: 'success', text1: 'Draft Saved' });
                  }}
                >
                  <Text style={styles.saveButtonText}>Save</Text>
                </TouchableOpacity>
                <TouchableOpacity
                  style={[styles.buttonBase, styles.submitButton]}
                  onPress={() => {
                     clearFilter();
                     handleSubmit();
                  }}
                  disabled={isSubmitting}
                >
                  <Text style={styles.submitButtonText}>Submit</Text>
                </TouchableOpacity>
              </View>
            </View>
          </>
        );
      }}
    </Formik>
  );
};

export default forwardRef(QuestionsForm);

// --- Styles ---

const styles = StyleSheet.create({
    outer: {
        marginHorizontal: 12,
        marginBottom: 8,
    },
    questionContainer: {
        borderWidth: 1,
        borderColor: '#E8E8E8',
        borderRadius: 8,
        padding: 8,
    },
    answerValue: {
        backgroundColor: Colors.colorWhite,
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 15,
        height: 30,
        width: 50,
        elevation: 3,
        shadowColor: "#000",
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.2,
        shadowRadius: 2,
    },
    answerText: {
        textAlign: 'center',
        fontSize: 12,
        fontWeight: 'bold',
    },
    observationInput: {
      borderRadius: 20,
      paddingLeft: 15,
      borderWidth: 1,
      marginRight: 8,
      flex: 1,
      fontSize: 12,
      height: 40,
    },
    errorTextStyle: {
        fontSize: 12,
        color: 'red',
        marginVertical: 2,
        paddingLeft: 8,
    },
    sectionHeaderContainer: {
        backgroundColor: 'white',
        borderWidth: 1,
        borderColor: Colors.colorTextInput,
        borderRadius: 8,
        marginHorizontal: 20,
        marginTop: 10,
        marginBottom: 5,
        padding: 10,
    },
    sectionHeaderTitleRow: {
        flexDirection: 'row',
        alignItems: 'center',
        marginBottom: 8,
    },
    sectionHeaderTitle: {
        color: '#9B9B9B',
        fontSize: 16,
        fontWeight: '700',
        marginRight: 8,
    },
    headerLine: {
        backgroundColor: '#9B9B9B',
        height: 0.5,
        flex: 1,
    },
    groupScoreText: {
      fontSize: 16,
      color: '#9B9B9B',
      textAlign: 'center',
      fontWeight: 'bold'
    },
    bottomBar: {
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        paddingVertical: 10,
        paddingHorizontal: 15,
        backgroundColor: 'white',
        borderTopWidth: 1,
        borderColor: '#e0e0e0',
    },
    buttonContainer: {
        flexDirection: 'row',
        flex: 1,
        justifyContent: 'flex-end',
    },
    buttonBase: {
        paddingVertical: 10,
        paddingHorizontal: 20,
        borderRadius: 20,
        justifyContent: 'center',
        alignItems: 'center',
        marginHorizontal: 5,
        elevation: 3,
        shadowColor: "#000",
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.2,
        shadowRadius: 2,
    },
    saveButton: {
        backgroundColor: 'white',
        borderWidth: 1,
        borderColor: '#C1AD84',
    },
    saveButtonText: {
        color: '#C1AD84',
        fontSize: 14,
        fontWeight: 'bold',
    },
    submitButton: {
        backgroundColor: '#C1AD84',
    },
    submitButtonText: {
        color: 'white',
        fontSize: 14,
        fontWeight: 'bold',
    },
});