import { useState, useEffect } from 'react';

/**
 * Custom Hook: useConclusionRemark
 * 
 * Purpose: Manages conclusion remark generation and finalization
 * 
 * Responsibilities:
 * - Fetches existing AI-generated conclusion
 * - Generates new conclusion using AI
 * - Finalizes conclusion and closes request
 * - Manages loading and submission states
 * - Handles navigation after successful closure
 * 
 * @param request - Current request object
 * @param requestIdentifier - Request number or UUID
 * @param isInitiator - Whether current user is the request initiator
 * @param refreshDetails - Function to refresh request data
 * @param onBack - Navigation callback
 * @param setActionStatus - Function to show action status modal
 * @param setShowActionStatusModal - Function to control action status modal visibility
 * @returns Object with conclusion state and action handlers
 */
export function useConclusionRemark(
  request: any,
  requestIdentifier: string,
  isInitiator: boolean,
  refreshDetails: () => Promise<void>,
  onBack?: () => void,
  setActionStatus?: (status: { success: boolean; title: string; message: string }) => void,
  setShowActionStatusModal?: (show: boolean) => void
) {
  // State: The conclusion remark text (editable by user)
  const [conclusionRemark, setConclusionRemark] = useState('');
  
  // State: Indicates if AI is currently generating conclusion
  const [conclusionLoading, setConclusionLoading] = useState(false);
  
  // State: Indicates if conclusion is being submitted to backend
  const [conclusionSubmitting, setConclusionSubmitting] = useState(false);
  
  // State: Tracks if current conclusion was AI-generated (shows badge in UI)
  const [aiGenerated, setAiGenerated] = useState(false);

  // State: Tracks number of AI generation attempts
  const [generationAttempts, setGenerationAttempts] = useState(0);
  
  // State: Tracks if AI generation failed (unable to generate)
  const [generationFailed, setGenerationFailed] = useState(false);
  
  // State: Tracks if max attempts (3 for success, 1 for fail) reached
  const [maxAttemptsReached, setMaxAttemptsReached] = useState(false);

  // State: Tracks number of AI generation failures
  const [failureAttempts, setFailureAttempts] = useState(0);

  /**
   * Function: fetchExistingConclusion
   * 
   * Purpose: Load existing AI-generated conclusion from backend
   * 
   * Use Case: When request is approved, final approver generates conclusion.
   * Initiator needs to review and finalize it before closing request.
   * 
   * Optimization: Check request object first before making API call
   * Process:
   * 1. Check if conclusion data is already in request object
   * 2. If not available, fetch from API
   * 3. Load into state if exists
   * 4. Mark as AI-generated if applicable
   */
  const fetchExistingConclusion = async () => {
    // Optimization: Check if conclusion data is already in request object
    // Request detail response includes conclusionRemark and aiGeneratedConclusion fields
    const existingConclusion = request?.conclusionRemark || request?.conclusion_remark;
    const existingAiConclusion = request?.aiGeneratedConclusion || request?.ai_generated_conclusion;
    
    if (existingConclusion || existingAiConclusion) {
      // Use data from request object - no API call needed
      setConclusionRemark(existingConclusion || existingAiConclusion);
      setAiGenerated(!!existingAiConclusion);
      return;
    }
    
    // Only fetch from API if not available in request object
    // This handles cases where request object might not have been refreshed yet
    try {
      // Lazy load: Import conclusion API only when needed
      const { getConclusion } = await import('@/services/conclusionApi');
      
      // API Call: Fetch existing conclusion (returns null if not found)
      const result = await getConclusion(request.requestId || requestIdentifier);
      
      if (result && (result.aiGeneratedRemark || result.finalRemark)) {
        // Load: Set the AI-generated or final remark
        // Handle null values by providing empty string fallback
        setConclusionRemark(result.finalRemark || result.aiGeneratedRemark || '');
        setAiGenerated(!!result.aiGeneratedRemark);
      }
    } catch (err) {
      // Only log non-404 errors (404 is handled gracefully in API)
      if ((err as any)?.response?.status !== 404) {
        console.error('[useConclusionRemark] Error fetching conclusion:', err);
      }
      // No conclusion yet - this is expected for newly approved requests
    }
  };

  /**
   * Function: handleGenerateConclusion
   * 
   * Purpose: Generate a new conclusion remark using AI
   * 
   * How it works:
   * 1. Sends request details to AI service
   * 2. AI analyzes approval history, comments, and request data
   * 3. Generates professional conclusion summarizing outcome
   * 4. User can edit the AI suggestion before finalizing
   * 
   * Process:
   * 1. Set loading state
   * 2. Call AI generation API
   * 3. Load generated text into textarea
   * 4. Mark as AI-generated (shows badge)
   * 5. Handle errors silently (user can type manually)
   */
  const handleGenerateConclusion = async () => {
    // Safety check: Prevent generation if max attempts already reached
    if (maxAttemptsReached) return;

    try {
      setConclusionLoading(true);
      setGenerationFailed(false);
      
      // Lazy load: Import conclusion API
      const { generateConclusion } = await import('@/services/conclusionApi');
      
      // API Call: Generate AI conclusion based on request data
      const result = await generateConclusion(request.requestId || requestIdentifier);
      
      const newAttempts = generationAttempts + 1;
      setGenerationAttempts(newAttempts);

      // Check for "unable to generate" or similar keywords in proper response
      const isUnableToGenerate = !result?.aiGeneratedRemark || 
        result.aiGeneratedRemark.toLowerCase().includes('unable to generate') ||
        result.aiGeneratedRemark.toLowerCase().includes('sorry');

      if (isUnableToGenerate) {
        const newFailures = failureAttempts + 1;
        setFailureAttempts(newFailures);
        
        if (newFailures >= 2) {
          setMaxAttemptsReached(true);
          setActionStatus?.({
            success: false,
            title: 'AI Generation Limit Reached',
            message: "We're unable to process a conclusion remark at this time after 2 attempts. Please proceed with a manual approach using the editor below."
          });
        } else {
          setActionStatus?.({
            success: false,
            title: 'System Note',
            message: "We're unable to process a conclusion remark at the moment. You have one more attempt remaining, or you can proceed manually."
          });
        }
        setShowActionStatusModal?.(true);
        setConclusionRemark(result?.aiGeneratedRemark || '');
        setAiGenerated(false);
        return;
      }

      // Success: Load AI-generated remark
      setConclusionRemark(result.aiGeneratedRemark);
      setAiGenerated(true);
      setFailureAttempts(0); // Reset failures on success

      // Limit to 2 successful attempts
      if (newAttempts >= 2) {
        setMaxAttemptsReached(true);
        setActionStatus?.({
          success: true,
          title: 'Maximum Attempts Reached',
          message: "You've reached the maximum of 2 regeneration attempts. Feel free to manually edit the current suggestion to fit your specific needs."
        });
        setShowActionStatusModal?.(true);
      }
    } catch (err) {
      console.error('[useConclusionRemark] AI generation failed:', err);
      const newFailures = failureAttempts + 1;
      setFailureAttempts(newFailures);
      setAiGenerated(false);

      if (newFailures >= 2) {
        setMaxAttemptsReached(true);
        setActionStatus?.({
          success: false,
          title: 'System Note',
          message: "We're unable to process your request at the moment. Since the maximum of 2 attempts is reached, please proceed with a manual approach."
        });
      } else {
        setActionStatus?.({
          success: false,
          title: 'System Note',
          message: "We're unable to process your request at the moment. You have one more attempt remaining, or you can proceed manually."
        });
      }
      setShowActionStatusModal?.(true);
    } finally {
      setConclusionLoading(false);
    }
  };

  /**
   * Function: handleFinalizeConclusion
   * 
   * Purpose: Submit conclusion remark and close the request
   * 
   * Business Logic:
   * - Only initiators can finalize approved or rejected requests
   * - Conclusion cannot be empty
   * - After finalization:
   *   → Request status changes to CLOSED
   *   → All participants are notified
   *   → Request moves to Closed Requests
   *   → Conclusion is permanently saved
   * 
   * Process:
   * 1. Validate conclusion is not empty
   * 2. Submit to backend
   * 3. Show success modal
   * 4. Refresh request data (status will be "closed")
   * 5. Navigate to Closed Requests after 2 seconds
   * 6. Handle errors with user-friendly messages
   */
  const handleFinalizeConclusion = async () => {
    // Validation: Ensure conclusion is not empty (strip HTML tags for validation)
    const textContent = conclusionRemark.replace(/<[^>]*>/g, '').trim();
    if (!textContent) {
      setActionStatus?.({
        success: false,
        title: 'Validation Error',
        message: 'Conclusion remark cannot be empty'
      });
      setShowActionStatusModal?.(true);
      return;
    }
    
    // Check character count (text content only, not HTML)
    if (textContent.length > 2000) {
      setActionStatus?.({
        success: false,
        title: 'Validation Error',
        message: 'Conclusion remark exceeds 2000 characters limit'
      });
      setShowActionStatusModal?.(true);
      return;
    }

    try {
      setConclusionSubmitting(true);
      
      // Lazy load: Import conclusion API
      const { finalizeConclusion } = await import('@/services/conclusionApi');
      
      // API Call: Submit conclusion and close request
      // Backend will:
      // - Update request status to CLOSED
      // - Save conclusion remark
      // - Send notifications to all participants
      // - Record closure timestamp
      await finalizeConclusion(request.requestId || requestIdentifier, conclusionRemark);
      
      // Success feedback
      setActionStatus?.({
        success: true,
        title: 'Request Closed with Successful Completion',
        message: 'The request has been finalized and moved to Closed Requests.'
      });
      setShowActionStatusModal?.(true);
      
      // Refresh: Update UI with new "closed" status
      await refreshDetails();
      
      /**
       * Navigate: Redirect to Closed Requests after showing success message
       * Delay allows user to see the success notification
       */
      setTimeout(() => {
        if (onBack) {
          // Use callback navigation if provided
          onBack();
          // Then navigate to closed requests
          setTimeout(() => {
            window.location.hash = '#/closed-requests';
          }, 100);
        } else {
          // Direct navigation
          window.location.hash = '#/closed-requests';
        }
      }, 2000); // 2 second delay
      
    } catch (err: any) {
      // Error feedback with backend message
      setActionStatus?.({
        success: false,
        title: 'Error',
        message: err.response?.data?.error || 'Failed to finalize conclusion'
      });
      setShowActionStatusModal?.(true);
    } finally {
      setConclusionSubmitting(false);
    }
  };

  /**
   * Effect: Auto-load existing conclusion when request becomes approved, rejected, or closed
   * 
   * Trigger: When request status changes to "approved", "rejected", or "closed" and user is initiator
   * Purpose: Load any conclusion generated by final approver (for approved) or AI (for rejected)
   * 
   * Optimization: 
   * 1. First check if conclusion data is already in request object (no API call needed)
   * 2. Only fetch from API if not available in request object
   */
  useEffect(() => {
    const status = request?.status?.toLowerCase();
    const shouldLoad = (status === 'approved' || status === 'rejected' || status === 'closed') 
      && isInitiator 
      && !conclusionRemark;
    
    if (!shouldLoad) return;
    
    // Check if conclusion data is already in request object
    const existingConclusion = request?.conclusionRemark || request?.conclusion_remark;
    const existingAiConclusion = request?.aiGeneratedConclusion || request?.ai_generated_conclusion;
    
    if (existingConclusion || existingAiConclusion) {
      // Use data from request object - no API call needed
      setConclusionRemark(existingConclusion || existingAiConclusion);
      setAiGenerated(!!existingAiConclusion);
    } else {
      // Only fetch from API if not available in request object
      fetchExistingConclusion();
    }
  }, [request?.status, request?.conclusionRemark, request?.aiGeneratedConclusion, isInitiator, conclusionRemark]);

  return {
    conclusionRemark,
    setConclusionRemark,
    conclusionLoading,
    conclusionSubmitting,
    aiGenerated,
    handleGenerateConclusion,
    handleFinalizeConclusion,
    generationAttempts,
    generationFailed,
    maxAttemptsReached
  };
}

