/**
 * Main CreateRequest component - Clean composition only
 * 
 * This component orchestrates the CreateRequest flow by:
 * - Composing layout structure
 * - Wiring up hooks and components
 * - Handling top-level callbacks
 * 
 * All business logic, API calls, and utilities are extracted to:
 * - hooks/ - Business logic and state management
 * - services/ - API operations
 * - utils/ - Pure utility functions
 * - components/ - UI components
 */

import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useAuth } from '@/contexts/AuthContext';
import { TemplateSelectionModal } from '@/components/modals/TemplateSelectionModal';
import { FilePreview } from '@/components/common/FilePreview';
import { PolicyViolationModal } from '@/components/modals/PolicyViolationModal';
import { downloadDocument } from '@/services/workflowApi';

// Custom Hooks
import { useCreateRequestForm, RequestTemplate } from '@/hooks/useCreateRequestForm';
import { useWizardNavigation } from '@/hooks/useWizardNavigation';
import { useRequestModals } from './hooks/useRequestModals';
import { useCreateRequestSubmission } from './hooks/useCreateRequestSubmission';
import { useCreateRequestHandlers } from './hooks/useCreateRequestHandlers';

// Constants
import { REQUEST_TEMPLATES } from './constants/requestTemplates';

// Services
import { getTemplates, WorkflowTemplate as BackendTemplate } from '@/services/workflowTemplateApi';
import { FileText } from 'lucide-react';

// Components
import { WizardStepper } from '@/components/workflow/CreateRequest/WizardStepper';
import { WizardFooter } from '@/components/workflow/CreateRequest/WizardFooter';
import { TemplateSelectionStep } from '@/components/workflow/CreateRequest/TemplateSelectionStep';
import { BasicInformationStep } from '@/components/workflow/CreateRequest/BasicInformationStep';
import { ApprovalWorkflowStep } from '@/components/workflow/CreateRequest/ApprovalWorkflowStep';
import { ParticipantsStep } from '@/components/workflow/CreateRequest/ParticipantsStep';
import { DocumentsStep } from '@/components/workflow/CreateRequest/DocumentsStep';
import { ReviewSubmitStep } from '@/components/workflow/CreateRequest/ReviewSubmitStep';
import { CreateRequestHeader } from './components/CreateRequestHeader';
import { CreateRequestContent } from './components/CreateRequestContent';
import { ValidationErrorModal } from './components/modals/ValidationErrorModal';
import { DocumentErrorModal } from './components/modals/DocumentErrorModal';

interface CreateRequestProps {
  onBack?: () => void;
  onSubmit?: (requestData: any) => void;
  requestId?: string;
  isEditMode?: boolean;
}

export function CreateRequest({
  onBack,
  onSubmit,
  requestId: propRequestId,
  isEditMode = false,
}: CreateRequestProps) {
  const params = useParams<{ requestId: string }>();
  const navigate = useNavigate();
  const editRequestId = params.requestId || propRequestId || '';
  const isEditing = isEditMode && !!editRequestId;
  const { user } = useAuth();

  const [adminTemplates, setAdminTemplates] = useState<RequestTemplate[]>([]);

  useEffect(() => {
    const fetchTemplates = async () => {
      try {
        const templates = await getTemplates();
        const mappedTemplates: RequestTemplate[] = templates.map((t: BackendTemplate) => ({
          id: t.id,
          name: t.name,
          description: t.description,
          category: t.category,
          icon: FileText,
          estimatedTime: t.estimatedTime,
          commonApprovers: t.approvers.map((a: any) => a.name),
          workflowApprovers: t.approvers,
          suggestedSLA: t.suggestedSLA,
          priority: t.priority,
          fields: t.fields || {}
        }));
        setAdminTemplates(mappedTemplates);
      } catch (error) {
        console.error('Failed to fetch admin templates:', error);
      }
    };
    fetchTemplates();
  }, []);

  const allTemplates = useMemo(() => [...REQUEST_TEMPLATES, ...adminTemplates], [adminTemplates]);

  // Form and state management hooks
  const {
    formData,
    updateFormData,
    selectedTemplate,
    setSelectedTemplate,
    loadingDraft,
    systemPolicy,
    documentPolicy,
    existingDocuments,
    setExistingDocuments,
  } = useCreateRequestForm(isEditing, editRequestId, allTemplates);

  const {
    currentStep,
    totalSteps,
    stepNames,
    isStepValid,
    nextStep: wizardNextStep,
    prevStep: wizardPrevStep,
    goToStep,
  } = useWizardNavigation(isEditing, selectedTemplate, formData);

  // Document management state
  const [documents, setDocuments] = useState<File[]>([]);
  const [documentsToDelete, setDocumentsToDelete] = useState<string[]>([]);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Modal management
  const {
    validationModal,
    policyViolationModal,
    documentErrorModal,
    openValidationModal,
    closeValidationModal,
    openPolicyViolationModal,
    closePolicyViolationModal,
    openDocumentErrorModal,
    closeDocumentErrorModal,
  } = useRequestModals();

  // Submission logic
  const { submitting, savingDraft, handleSubmit, handleSaveDraft } =
    useCreateRequestSubmission({
      formData,
      selectedTemplate,
      documents,
      documentsToDelete,
      user: user!,
      isEditing,
      editRequestId,
      onSubmit,
    });

  // Event handlers
  const {
    showTemplateModal,
    setShowTemplateModal,
    previewDocument,
    selectTemplate,
    handleTemplateSelection,
    nextStep,
    prevStep,
    handlePreviewDocument,
    closePreview,
  } = useCreateRequestHandlers({
    selectedTemplate,
    setSelectedTemplate,
    updateFormData,
    formData,
    currentStep,
    isStepValid,
    wizardNextStep,
    wizardPrevStep,
    user: user!,
    openValidationModal,
    systemPolicy,
    onPolicyViolation: openPolicyViolationModal,
    onSubmit,
    goToStep,
  });

  // Handle back button: 
  // - Steps 1, 3, or 4: Navigate back to previous screen (browser history)
  // - Other steps: Go to previous step in wizard
  const handleBackButton = useCallback(() => {
    // If on the first step (Template Selection), always go back to dashboard
    // This prevents infinite loops if the user was redirected here from an error page
    if (currentStep === 1) {
      navigate('/dashboard', { replace: true });
      return;
    }

    // For other major steps (3=Approval, 4=Participants), we might want to go back to prev screen
    // But for consistency and safety against loops, let's treat "Back" as "Previous Step" 
    // or explicit exit if at the start of a flow.

    // Actually, keep the history logic ONLY for later steps if needed, but Step 1 MUST be explicit.
    if (currentStep === 3 || currentStep === 4) {
      // ... existing logic for these steps if we want to keep it, 
      // but typically "Back" in a wizard should go to previous wizard step.
      // However, the original code had this specific logic. 
      // Let's defer to prevStep() for wizard navigation, and only use history/dashboard for exit.

      if (onBack) {
        onBack();
      } else {
        if (window.history.length > 1) {
          window.history.back();
        } else {
          navigate('/dashboard', { replace: true });
        }
      }
    } else {
      // On other steps (2, 5, 6), go to previous step in wizard
      prevStep();
    }
  }, [currentStep, onBack, navigate, prevStep]);

  // Sync documents from formData only on initial mount (when loading draft)
  const isInitialMount = useRef(true);
  const documentsSyncedRef = useRef(false);

  useEffect(() => {
    // Only sync from formData on initial mount or when loading a draft
    if (isInitialMount.current && formData.documents && formData.documents.length > 0 && !documentsSyncedRef.current) {
      setDocuments(formData.documents);
      documentsSyncedRef.current = true;
    }
    isInitialMount.current = false;
  }, [formData.documents]);

  // Update formData.documents when documents change (one-way sync from local state to formData)
  // Use a ref to prevent circular updates
  const isUpdatingFromFormData = useRef(false);
  const prevDocumentsRef = useRef(documents);

  useEffect(() => {
    // Skip if we're currently syncing from formData
    if (isUpdatingFromFormData.current) {
      isUpdatingFromFormData.current = false;
      prevDocumentsRef.current = documents;
      return;
    }

    // Only update if documents actually changed
    if (prevDocumentsRef.current !== documents) {
      updateFormData('documents', documents);
      prevDocumentsRef.current = documents;
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [documents]);

  // Render step content
  const renderStepContent = () => {
    switch (currentStep) {
      case 1:
        return (
          <TemplateSelectionStep
            templates={REQUEST_TEMPLATES}
            selectedTemplate={selectedTemplate}
            onSelectTemplate={selectTemplate}
            adminTemplates={adminTemplates}
          />
        );
      case 2:
        return (
          <BasicInformationStep
            formData={formData}
            selectedTemplate={selectedTemplate}
            updateFormData={updateFormData}
          />
        );
      case 3:
        return (
          <ApprovalWorkflowStep
            formData={formData}
            updateFormData={updateFormData}
            systemPolicy={systemPolicy}
            onValidationError={(error) =>
              openValidationModal(
                error.type as 'error' | 'self-assign' | 'not-found',
                error.email,
                error.message
              )
            }
            onPolicyViolation={openPolicyViolationModal}
          />
        );
      case 4:
        return (
          <ParticipantsStep
            formData={formData}
            updateFormData={updateFormData}
            onValidationError={(error) =>
              openValidationModal(
                error.type as 'error' | 'self-assign' | 'not-found',
                error.email,
                error.message
              )
            }
            initiatorEmail={(user as any)?.email || ''}
          />
        );
      case 5:
        return (
          <DocumentsStep
            documentPolicy={documentPolicy}
            isEditing={isEditing}
            documents={documents}
            existingDocuments={existingDocuments}
            documentsToDelete={documentsToDelete}
            onDocumentsChange={setDocuments}
            onExistingDocumentsChange={setExistingDocuments}
            onDocumentsToDeleteChange={setDocumentsToDelete}
            onPreviewDocument={handlePreviewDocument}
            onDocumentErrors={(errors) => openDocumentErrorModal(errors)}
            fileInputRef={fileInputRef}
          />
        );
      case 6:
        return (
          <ReviewSubmitStep
            formData={formData}
            selectedTemplate={selectedTemplate}
          />
        );
      default:
        return null;
    }
  };

  // Loading state
  if (loadingDraft) {
    return (
      <div
        className="min-h-screen bg-gray-50 flex items-center justify-center"
        data-testid="create-request-loading"
      >
        <div className="text-center">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div>
          <p className="text-gray-600">Loading draft...</p>
        </div>
      </div>
    );
  }

  // Main render
  return (
    <div
      className="h-full flex flex-col bg-gradient-to-br from-gray-50 to-white"
      data-testid="create-request"
    >
      <CreateRequestHeader
        isEditing={isEditing}
        currentStep={currentStep}
        totalSteps={totalSteps}
        stepNames={stepNames}
        onBack={handleBackButton}
      />

      <WizardStepper
        currentStep={currentStep}
        totalSteps={totalSteps}
        stepNames={stepNames}
      />

      <CreateRequestContent>{renderStepContent()}</CreateRequestContent>

      <WizardFooter
        currentStep={currentStep}
        totalSteps={totalSteps}
        isStepValid={isStepValid()}
        onPrev={prevStep}
        onNext={nextStep}
        onSubmit={handleSubmit}
        onSaveDraft={handleSaveDraft}
        submitting={submitting}
        savingDraft={savingDraft}
        loadingDraft={loadingDraft}
        isEditing={isEditing}
      />

      {/* Modals */}
      <TemplateSelectionModal
        open={showTemplateModal}
        onClose={() => setShowTemplateModal(false)}
        onSelectTemplate={handleTemplateSelection}
      />

      {previewDocument && (
        <FilePreview
          fileName={previewDocument.fileName}
          fileType={previewDocument.fileType}
          fileUrl={previewDocument.fileUrl}
          fileSize={previewDocument.fileSize}
          open={!!previewDocument}
          onClose={closePreview}
          onDownload={async () => {
            if (previewDocument.file) {
              const link = document.createElement('a');
              link.href = previewDocument.fileUrl;
              link.download = previewDocument.fileName;
              document.body.appendChild(link);
              link.click();
              document.body.removeChild(link);
            } else if (previewDocument.documentId) {
              await downloadDocument(previewDocument.documentId);
            }
          }}
          attachmentId={previewDocument.documentId}
        />
      )}

      <ValidationErrorModal
        modal={validationModal}
        onClose={closeValidationModal}
      />

      <DocumentErrorModal
        modal={documentErrorModal}
        documentPolicy={documentPolicy}
        onClose={closeDocumentErrorModal}
      />

      <PolicyViolationModal
        open={policyViolationModal.open}
        onClose={closePolicyViolationModal}
        violations={policyViolationModal.violations}
        policyDetails={{
          maxApprovalLevels: systemPolicy.maxApprovalLevels,
          maxParticipants: systemPolicy.maxParticipants,
          allowSpectators: systemPolicy.allowSpectators,
          maxSpectators: systemPolicy.maxSpectators,
        }}
      />
    </div>
  );
}
