import React, { useState, useEffect, useCallback, useRef } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import { useNavigation } from '@/contexts/NavigationContext';
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { MessageSquare } from 'lucide-react';
import { toast } from 'sonner';
import { personasApi, focusGroupsApi } from '@/lib/api';
import ProgressModal from '@/components/ui/ProgressModal';
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Persona } from "@/types/persona";

// Custom hooks
import { useFocusGroupAutoSave } from '@/hooks/useFocusGroupAutoSave';
import { useFolderManagement } from '@/hooks/useFolderManagement';
import { usePersonaFiltering } from '@/hooks/usePersonaFiltering';
import { useDiscussionGuideGeneration } from '@/hooks/useDiscussionGuideGeneration';

// Components
import { SaveStatusIndicator } from '@/components/ui/SaveStatusIndicator';
import { FolderSidebar } from '@/components/focus-group-session/FolderSidebar';
import { PersonaFilterDialog } from '@/components/focus-group-session/PersonaFilterDialog';
import { CopyGuideDialog } from '@/components/focus-group-session/CopyGuideDialog';
import { SetupTab } from '@/components/focus-group-session/SetupTab';
import { ReviewTab } from '@/components/focus-group-session/ReviewTab';
import { ParticipantsTab } from '@/components/focus-group-session/ParticipantsTab';

// Form schema
const formSchema = z.object({
  researchBrief: z.string().min(10, {
    message: "Research brief must be at least 10 characters.",
  }),
  focusGroupName: z.string().min(3, {
    message: "Focus group name must be at least 3 characters.",
  }),
  discussionTopics: z.string().min(10, {
    message: "Discussion topics are required.",
  }),
  duration: z.string().min(1, {
    message: "Duration is required.",
  }),
  llm_model: z.string().optional(),
  reasoning_effort: z.string().optional(),
  verbosity: z.string().optional(),
});

interface FocusGroupModeratorProps {
  draftToEdit?: any | null;
  onDraftSaved?: () => void;
  preSelectedParticipants?: string[];
}

export default function FocusGroupModerator({
  draftToEdit,
  onDraftSaved,
  preSelectedParticipants = []
}: FocusGroupModeratorProps = {}) {
  const navigate = useNavigate();
  const { setPreviousRoute, navigationState, clearNavigationState } = useNavigation();

  // Tab state
  const [activeTab, setActiveTab] = useState('setup');

  // Core state
  const [draftFocusGroupId, setDraftFocusGroupId] = useState<string | null>(null);
  const [selectedParticipants, setSelectedParticipants] = useState<string[]>([]);
  const [backendAssets, setBackendAssets] = useState<any[]>([]);
  const [personas, setPersonas] = useState<any[]>([]);
  const [isLoadingPersonas, setIsLoadingPersonas] = useState(false);

  // Copy guide dialog state
  const [isCopyGuideModalOpen, setIsCopyGuideModalOpen] = useState(false);

  // Track if draft has been loaded
  const draftLoadedRef = useRef(false);

  // Initialize form
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      researchBrief: "",
      focusGroupName: "",
      discussionTopics: "",
      duration: "60",
      llm_model: "gemini-3-pro-preview",
      reasoning_effort: "medium",
      verbosity: "medium",
    },
  });

  // Custom hooks
  const folderManagement = useFolderManagement();

  const filtering = usePersonaFiltering({
    personas,
    selectedFolder: folderManagement.selectedFolder,
  });

  const guideGeneration = useDiscussionGuideGeneration({
    form,
  });

  const autoSave = useFocusGroupAutoSave({
    form,
    selectedParticipants,
    backendAssets,
    draftFocusGroupId,
    draftToEdit,
    activeTab,
    onDraftIdChange: setDraftFocusGroupId,
  });

  // Fetch personas on mount
  useEffect(() => {
    const fetchPersonas = async () => {
      setIsLoadingPersonas(true);
      try {
        const response = await personasApi.getAll();
        if (Array.isArray(response.data) && response.data.length > 0) {
          setPersonas(response.data);
        } else {
          toast.warning("No participants available");
        }
      } catch (error) {
        console.error("Error fetching personas:", error);
        toast.error("Failed to load participants");
      } finally {
        setIsLoadingPersonas(false);
      }
    };

    fetchPersonas();
  }, []);

  // Fetch backend assets
  const fetchBackendAssets = useCallback(async (focusGroupId: string) => {
    try {
      const response = await focusGroupsApi.getAssets(focusGroupId);
      setBackendAssets(response.data.assets || []);
    } catch (error) {
      console.error("Error fetching backend assets:", error);
      toast.error("Failed to load asset information");
    }
  }, []);

  // Load draft data when editing
  useEffect(() => {
    if (!draftToEdit) {
      draftLoadedRef.current = false;
      return;
    }

    if (draftToEdit && !draftLoadedRef.current) {
      autoSave.setIsLoadingDraft(true);
      draftLoadedRef.current = true;

      const draftId = draftToEdit.id || draftToEdit._id;
      setDraftFocusGroupId(draftId);

      if (draftId) {
        fetchBackendAssets(draftId);
      }

      // Load form data
      if (draftToEdit.name) form.setValue('focusGroupName', draftToEdit.name);
      if (draftToEdit.description || draftToEdit.objective) {
        form.setValue('researchBrief', draftToEdit.description || draftToEdit.objective || '');
      }
      if (draftToEdit.topic) form.setValue('discussionTopics', draftToEdit.topic);
      if (draftToEdit.duration) form.setValue('duration', draftToEdit.duration.toString());
      if (draftToEdit.llm_model) form.setValue('llm_model', draftToEdit.llm_model);
      if (draftToEdit.reasoning_effort) form.setValue('reasoning_effort', draftToEdit.reasoning_effort);
      if (draftToEdit.verbosity) form.setValue('verbosity', draftToEdit.verbosity);

      // Load discussion guide
      if (draftToEdit.discussionGuide) {
        guideGeneration.setDiscussionGuide(draftToEdit.discussionGuide);
        if (!navigationState.focusGroupTab || navigationState.previousRoute !== '/focus-groups') {
          setActiveTab('review');
        }
      }

      // Load participants
      if (draftToEdit.participants && Array.isArray(draftToEdit.participants)) {
        setSelectedParticipants(draftToEdit.participants);
      }

      // Set last saved data
      autoSave.setLastSavedData({
        name: draftToEdit.name || '',
        description: draftToEdit.description || draftToEdit.objective || '',
        objective: draftToEdit.description || draftToEdit.objective || '',
        topic: draftToEdit.topic || '',
        duration: draftToEdit.duration || 60,
        llm_model: draftToEdit.llm_model || 'gemini-3-pro-preview',
        reasoning_effort: draftToEdit.reasoning_effort || 'medium',
        verbosity: draftToEdit.verbosity || 'medium',
        participants: draftToEdit.participants || [],
        participants_count: (draftToEdit.participants || []).length,
        status: 'draft',
        date: draftToEdit.date || new Date().toISOString(),
        uploadedAssets: backendAssets.map(a => a.filename || a.original_name || 'unknown')
      });

      toast.success("Draft focus group loaded", {
        description: "Continue editing your focus group setup"
      });

      setTimeout(() => {
        autoSave.setIsLoadingDraft(false);
      }, 1000);
    }
  }, [draftToEdit, form, fetchBackendAssets, navigationState, autoSave, guideGeneration, backendAssets]);

  // Handle pre-selected participants
  useEffect(() => {
    if (preSelectedParticipants.length > 0) {
      setSelectedParticipants(preSelectedParticipants);
      setActiveTab('participants');
    }
  }, [preSelectedParticipants]);

  // Handle navigation state for returning from persona details
  useEffect(() => {
    if (navigationState.focusGroupTab && navigationState.previousRoute === '/focus-groups') {
      setTimeout(() => {
        setActiveTab(navigationState.focusGroupTab);
        clearNavigationState();
      }, 0);
    }
  }, [navigationState.focusGroupTab, draftToEdit, clearNavigationState]);

  // Revert to setup tab when generation is cancelled
  useEffect(() => {
    if (!guideGeneration.guideGenerationState.isGenerating &&
        !guideGeneration.guideGenerationState.isCancelling &&
        guideGeneration.guideGenerationState.taskId === null &&
        activeTab === 'review' &&
        !guideGeneration.discussionGuide) {
      setActiveTab('setup');
    }
  }, [guideGeneration.guideGenerationState, activeTab, guideGeneration.discussionGuide]);

  // Handle participant selection
  const handleParticipantSelection = useCallback((id: string) => {
    setSelectedParticipants(prev => {
      const isSelected = prev.includes(id);
      return isSelected ? prev.filter(pId => pId !== id) : [...prev, id];
    });
  }, []);

  // Handle persona view details
  const handlePersonaViewDetails = useCallback((persona: Persona) => {
    setPreviousRoute('/focus-groups', {
      focusGroupId: draftFocusGroupId,
      focusGroupTab: 'participants',
      isNewFocusGroup: !draftToEdit,
      focusGroupData: {
        name: form.getValues('focusGroupName'),
        description: form.getValues('researchBrief'),
        selectedParticipants: selectedParticipants,
        discussionGuide: guideGeneration.discussionGuide,
      }
    });
    navigate(`/synthetic-users/${persona.id}`);
  }, [setPreviousRoute, draftFocusGroupId, draftToEdit, form, selectedParticipants, guideGeneration.discussionGuide, navigate]);

  // Handle form submission (generate discussion guide)
  const handleSubmit = useCallback(async (e: React.FormEvent) => {
    e.preventDefault();

    const isValid = await form.trigger();
    if (!isValid) return;

    const values = form.getValues();

    try {
      let focusGroupId = draftFocusGroupId;

      if (!focusGroupId) {
        const draftData = {
          name: values.focusGroupName,
          status: 'draft',
          participants: selectedParticipants,
          participants_count: selectedParticipants.length,
          date: new Date().toISOString(),
          duration: parseInt(values.duration),
          topic: values.discussionTopics.split(',')[0].trim().toLowerCase().replace(/\s+/g, '-'),
          description: values.researchBrief,
          objective: values.researchBrief,
          llm_model: values.llm_model,
          reasoning_effort: values.reasoning_effort,
          verbosity: values.verbosity,
        };

        const savedDraft = await focusGroupsApi.create(draftData);
        focusGroupId = savedDraft.data.focus_group_id || savedDraft.data.id || savedDraft.data._id;
        setDraftFocusGroupId(focusGroupId);
      }

      // Update focus group before generating
      if (focusGroupId) {
        const preUpdateData = {
          name: values.focusGroupName,
          participants: selectedParticipants,
          participants_count: selectedParticipants.length,
          duration: parseInt(values.duration),
          topic: values.discussionTopics.split(',')[0].trim().toLowerCase().replace(/\s+/g, '-'),
          description: values.researchBrief,
          objective: values.researchBrief,
          llm_model: values.llm_model,
          reasoning_effort: values.reasoning_effort,
          verbosity: values.verbosity
        };
        await focusGroupsApi.update(focusGroupId, preUpdateData);
      }

      // Generate discussion guide
      const guide = await guideGeneration.generateDiscussionGuide(values, focusGroupId);

      if (!guide || (typeof guide === 'string' && guide.trim() === '')) {
        return; // Cancelled
      }

      guideGeneration.setDiscussionGuide(guide);

      // Save with discussion guide
      if (focusGroupId) {
        const updateData = {
          name: values.focusGroupName,
          status: 'draft',
          participants: selectedParticipants,
          participants_count: selectedParticipants.length,
          date: new Date().toISOString(),
          duration: parseInt(values.duration),
          topic: values.discussionTopics.split(',')[0].trim().toLowerCase().replace(/\s+/g, '-'),
          description: values.researchBrief,
          objective: values.researchBrief,
          llm_model: values.llm_model,
          reasoning_effort: values.reasoning_effort,
          verbosity: values.verbosity,
          discussionGuide: guide
        };

        await focusGroupsApi.update(focusGroupId, updateData);
        toast.success("Progress saved as draft");
      }

      setActiveTab('review');
      toast.success("Discussion guide generated", {
        description: "Review and edit before proceeding",
      });

    } catch (error: any) {
      console.error("Error in focus group creation flow:", error);
      toast.error("Discussion guide generation failed", {
        description: "Please go back to the setup tab and try generating again.",
        duration: 8000,
      });
    }
  }, [draftFocusGroupId, form, selectedParticipants, guideGeneration]);

  // Handle copying discussion guide from another focus group
  const handleCopyDiscussionGuide = useCallback(async (sourceFocusGroup: any) => {
    if (!sourceFocusGroup || !sourceFocusGroup.discussionGuide) {
      toast.error("Selected focus group does not have a discussion guide");
      return;
    }

    guideGeneration.setDiscussionGuide(sourceFocusGroup.discussionGuide);

    // Update draft with copied guide
    if (draftFocusGroupId) {
      try {
        const values = form.getValues();
        const updateData = {
          name: values.focusGroupName,
          status: 'draft',
          participants: selectedParticipants,
          participants_count: selectedParticipants.length,
          duration: parseInt(values.duration || '60'),
          topic: values.discussionTopics || '',
          description: values.researchBrief || '',
          objective: values.researchBrief || '',
          llm_model: values.llm_model || 'gemini-3-pro-preview',
          reasoning_effort: values.reasoning_effort || 'medium',
          verbosity: values.verbosity || 'medium',
          discussionGuide: sourceFocusGroup.discussionGuide
        };

        await focusGroupsApi.update(draftFocusGroupId, updateData);
      } catch (error) {
        console.error("Failed to update focus group with copied discussion guide:", error);
        toast.error("Failed to save copied discussion guide");
      }
    }

    setIsCopyGuideModalOpen(false);
    setActiveTab('review');
    toast.success("Discussion guide copied successfully", {
      description: `Copied from "${sourceFocusGroup.name}"`,
    });
  }, [draftFocusGroupId, form, selectedParticipants, guideGeneration]);

  // Handle starting focus group
  const handleStartFocusGroup = useCallback(async () => {
    if (!form.getValues().focusGroupName) {
      toast.error("Missing focus group name");
      return;
    }

    if (!guideGeneration.discussionGuide) {
      toast.error("Missing discussion guide");
      return;
    }

    if (selectedParticipants.length < 1) {
      toast.error("Not enough participants", {
        description: "Please select at least one participant",
      });
      return;
    }

    try {
      toast.loading("Creating focus group...");
      const values = form.getValues();
      let focusGroupId = draftFocusGroupId;

      if (focusGroupId) {
        const updatedData = {
          name: values.focusGroupName,
          status: 'in-progress',
          participants: selectedParticipants,
          participants_count: selectedParticipants.length,
          date: new Date().toISOString(),
          duration: parseInt(values.duration),
          topic: values.discussionTopics.split(',')[0].trim().toLowerCase().replace(/\s+/g, '-'),
          description: values.researchBrief,
          objective: values.researchBrief,
          discussionGuide: guideGeneration.discussionGuide
        };

        await focusGroupsApi.update(focusGroupId, updatedData);
        if (onDraftSaved) onDraftSaved();
      } else {
        const focusGroupData = {
          name: values.focusGroupName,
          status: 'in-progress',
          participants: selectedParticipants,
          participants_count: selectedParticipants.length,
          date: new Date().toISOString(),
          duration: parseInt(values.duration),
          topic: values.discussionTopics.split(',')[0].trim().toLowerCase().replace(/\s+/g, '-'),
          discussionGuide: guideGeneration.discussionGuide
        };

        const response = await focusGroupsApi.create(focusGroupData);
        focusGroupId = response.data.focus_group_id;
      }

      toast.dismiss();
      toast.success("Focus group created successfully");
      navigate(`/focus-groups/${focusGroupId}`);
    } catch (error) {
      toast.dismiss();
      console.error("Failed to start focus group:", error);
      toast.error("Failed to create focus group");
    }
  }, [form, guideGeneration.discussionGuide, selectedParticipants, draftFocusGroupId, onDraftSaved, navigate]);

  return (
    <>
      <SaveStatusIndicator status={autoSave.autoSaveStatus} />

      <div className="glass-panel rounded-xl p-6">
        <div className="flex items-center gap-2 mb-6">
          <MessageSquare className="h-5 w-5 text-primary" />
          <h2 className="font-sf text-xl font-semibold">AI Focus Group Moderator</h2>
        </div>

        {/* Progress Modal */}
        <ProgressModal
          isOpen={guideGeneration.isGuideProgressModalOpen}
          onClose={() => guideGeneration.setIsGuideProgressModalOpen(false)}
          isActive={guideGeneration.guideGenerationState.isGenerating}
          isComplete={guideGeneration.guideGenerationState.isComplete}
          hasError={guideGeneration.guideGenerationState.hasError}
          isCancelling={guideGeneration.guideGenerationState.isCancelling}
          taskId={guideGeneration.guideGenerationState.taskId}
          title="Generating Discussion Guide"
          description="Creating your discussion guide based on the research objectives. This typically takes 30-60 seconds."
          onCancel={guideGeneration.guideGenerationControls.cancelGeneration}
          onComplete={guideGeneration.handleGuideProgressComplete}
        />

        <Tabs value={activeTab} onValueChange={setActiveTab}>
          <TabsList className="grid w-full grid-cols-3 mb-6">
            <TabsTrigger value="setup">Setup</TabsTrigger>
            <TabsTrigger value="review">Review & Edit</TabsTrigger>
            <TabsTrigger value="participants">Participants</TabsTrigger>
          </TabsList>

          <TabsContent value="setup">
            <SetupTab
              form={form}
              onSubmit={handleSubmit}
              isGenerating={guideGeneration.guideGenerationState.isGenerating}
              draftFocusGroupId={draftFocusGroupId}
              backendAssets={backendAssets}
              onAssetsChange={setBackendAssets}
              onCopyGuideClick={() => setIsCopyGuideModalOpen(true)}
            />
          </TabsContent>

          <TabsContent value="review">
            <ReviewTab
              discussionGuide={guideGeneration.discussionGuide}
              backendAssets={backendAssets}
              draftFocusGroupId={draftFocusGroupId}
              onSaveGuide={guideGeneration.handleSaveDiscussionGuide}
              onDownloadGuide={guideGeneration.handleDownloadDiscussionGuide}
              isDownloading={guideGeneration.isDownloadingGuide}
              guideGenerationState={guideGeneration.guideGenerationState}
              onEditingChange={guideGeneration.handleEditingStateChange}
              onNavigateToSetup={() => setActiveTab('setup')}
              onNavigateToParticipants={() => setActiveTab('participants')}
              isJsonFormat={guideGeneration.isJsonFormat}
            />
          </TabsContent>

          <TabsContent value="participants">
            <ParticipantsTab
              personas={personas}
              filteredPersonas={filtering.filteredPersonas}
              selectedParticipants={selectedParticipants}
              onParticipantToggle={handleParticipantSelection}
              onViewDetails={handlePersonaViewDetails}
              searchTerm={filtering.searchTerm}
              onSearchChange={filtering.setSearchTerm}
              activeFilters={filtering.activeFilters}
              onOpenFilter={filtering.openFilterDialog}
              isLoading={isLoadingPersonas}
              folderSidebar={
                <FolderSidebar
                  folders={folderManagement.folders}
                  selectedFolder={folderManagement.selectedFolder}
                  onSelectFolder={folderManagement.setSelectedFolder}
                  personas={personas}
                  isCreatingFolder={folderManagement.isCreatingFolder}
                  onStartCreateFolder={() => folderManagement.setIsCreatingFolder(true)}
                  newFolderName={folderManagement.newFolderName}
                  onNewFolderNameChange={folderManagement.setNewFolderName}
                  onConfirmCreateFolder={folderManagement.createNewFolder}
                  onCancelCreateFolder={folderManagement.cancelFolderCreation}
                  folderToRename={folderManagement.folderToRename}
                  renameFolderName={folderManagement.renameFolderName}
                  onRenameFolderNameChange={folderManagement.setRenameFolderName}
                  onStartRenameFolder={folderManagement.startRenameFolder}
                  onConfirmRenameFolder={folderManagement.completeRenameFolder}
                  onCancelRenameFolder={folderManagement.cancelRenameFolder}
                />
              }
              onNavigateToReview={() => setActiveTab('review')}
              onStartFocusGroup={handleStartFocusGroup}
              canStart={selectedParticipants.length >= 1 && !!guideGeneration.discussionGuide}
            />

            {/* Filter Dialog */}
            <PersonaFilterDialog
              open={filtering.isFilterOpen}
              onOpenChange={(open) => {
                if (open) {
                  filtering.openFilterDialog();
                } else {
                  filtering.setIsFilterOpen(false);
                }
              }}
              workingFilters={filtering.workingFilters}
              personas={personas}
              getFilterOptions={filtering.getFilterOptions}
              getFilteredOptions={filtering.getFilteredOptions}
              onToggleFilter={filtering.toggleFilter}
              onApply={filtering.applyFilters}
              onReset={filtering.resetFilters}
            />
          </TabsContent>
        </Tabs>

        {/* Copy Guide Dialog */}
        <CopyGuideDialog
          open={isCopyGuideModalOpen}
          onOpenChange={setIsCopyGuideModalOpen}
          onCopyGuide={handleCopyDiscussionGuide}
          excludeFocusGroupId={draftFocusGroupId}
        />
      </div>
    </>
  );
}
