import React, { useState, useCallback, useRef } from 'react';
import {
  Tabs,
  Tab,
  Box,
} from '@mui/material';
import { SxProps, Theme } from '@mui/material';

import { ChatQuery } from './ChatQuery';
import { MessageList, MessageData } from './Message';
import { SetSnackType } from './Snack';
import { Conversation } from './Conversation';

interface ResumeBuilderProps {
  connectionBase: string,
  sessionId: string | undefined,
  setSnack: SetSnackType,
  sx?: SxProps<Theme>;
};

/**
 * ResumeBuilder component
 * 
 * A responsive component that displays job descriptions, generated resumes and fact checks
 * with different layouts for mobile and desktop views.
 */
const ResumeBuilder: React.FC<ResumeBuilderProps> = ({
  sx,
  connectionBase,
  sessionId,
  setSnack

}) => {
  // State for editing job description
  const [hasJobDescription, setHasJobDescription] = useState<boolean>(false);
  const [hasResume, setHasResume] = useState<boolean>(false);
  const [hasFacts, setHasFacts] = useState<boolean>(false);
  const jobConversationRef = useRef<any>(null);
  const resumeConversationRef = useRef<any>(null);
  const factsConversationRef = useRef<any>(null);

  const [activeTab, setActiveTab] = useState<number>(0);

  /**
   * Handle tab change for mobile view
   */
  const handleTabChange = (_event: React.SyntheticEvent, newValue: number): void => {
    setActiveTab(newValue);
  };

  const handleJobQuery = (query: string) => {
    console.log(`handleJobQuery: ${query} -- `, jobConversationRef.current ? ' sending' : 'no handler');
    jobConversationRef.current?.submitQuery(query);
  };

  const handleResumeQuery = (query: string) => {
    console.log(`handleResumeQuery: ${query} -- `, resumeConversationRef.current ? ' sending' : 'no handler');
    resumeConversationRef.current?.submitQuery(query);
  };

  const handleFactsQuery = (query: string) => {
    console.log(`handleFactsQuery: ${query} -- `, factsConversationRef.current ? ' sending' : 'no handler');
    factsConversationRef.current?.submitQuery(query);
  };

  const filterJobDescriptionMessages = useCallback((messages: MessageList): MessageList => {
    if (messages === undefined || messages.length === 0) {
      return [];
    }
    console.log("filterJobDescriptionMessages disabled", messages)
    if (messages.length > 1) {
      setHasResume(true);
    }

    messages[0].role = 'content';
    messages[0].title = 'Job Description';
    messages[0].disableCopy = false;

    return messages;

    // let reduced = messages.filter((m, i) => {
    //   const keep = (m.metadata?.origin || m.origin || "no origin") === 'job_description';
    //   if ((m.metadata?.origin || m.origin || "no origin") === 'resume') {
    //     setHasResume(true);
    //   }
    //   // if (!keep) {
    //   //   console.log(`filterJobDescriptionMessages: ${i + 1} filtered:`, m);
    //   // } else {
    //   //   console.log(`filterJobDescriptionMessages: ${i + 1}:`, m);
    //   // }

    //   return keep;
    // });

    // /* If Resume hasn't occurred yet and there is still more than one message,
    //  * resume has been generated. */
    // if (!hasResume && reduced.length > 1) {
    //   setHasResume(true);
    // }

    // if (reduced.length > 0) {
    //   // First message is always 'content'
    //   reduced[0].title = 'Job Description';
    //   reduced[0].role = 'content';
    //   setHasJobDescription(true);
    // }

    // /* Filter out any messages which the server injected for state management */
    // reduced = reduced.filter(m => m.display !== "hide");

    // return reduced;
  }, [setHasResume/*, setHasJobDescription, hasResume*/]);

  const filterResumeMessages = useCallback((messages: MessageList): MessageList => {
    if (messages === undefined || messages.length === 0) {
      return [];
    }
    console.log("filterResumeMessages disabled")
    if (messages.length > 3) {
      setHasFacts(true);
    }
    return messages;

    // let reduced = messages.filter((m, i) => {
    //   const keep = (m.metadata?.origin || m.origin || "no origin") === 'resume';
    //   if ((m.metadata?.origin || m.origin || "no origin") === 'fact_check') {
    //     setHasFacts(true);
    //   }
    //   if (!keep) {
    //     console.log(`filterResumeMessages: ${i + 1} filtered:`, m);
    //   } else {
    //     console.log(`filterResumeMessages: ${i + 1}:`, m);
    //   }
    //   return keep;
    // });

    // /* If there is more than one message, it is user: "...JOB_DESCRIPTION...", assistant: "...RESUME..."
    //  * which means a resume has been generated. */
    // if (reduced.length > 1) {
    //   /* Remove the assistant message from the UI */
    //   if (reduced[0].role === "user") {
    //     reduced.splice(0, 1);
    //   }
    // }

    // /* If Fact Check hasn't occurred yet and there is still more than one message,
    //  * facts have have been generated. */
    // if (!hasFacts && reduced.length > 1) {
    //   setHasFacts(true);
    // }

    // /* Filter out any messages which the server injected for state management */
    // reduced = reduced.filter(m => m.display !== "hide");

    // /* If there are any messages, there is a resume */
    // if (reduced.length > 0) {
    //   // First message is always 'content'
    //   reduced[0].title = 'Resume';
    //   reduced[0].role = 'content';
    //   setHasResume(true);
    // }

    // return reduced;
  }, [/*setHasResume, hasFacts,*/ setHasFacts]);

  const filterFactsMessages = useCallback((messages: MessageList): MessageList => {
    if (messages === undefined || messages.length === 0) {
      return [];
    }
    console.log("filterFactsMessages disabled")
    return messages;

    // messages.forEach((m, i) => console.log(`filterFactsMessages: ${i + 1}:`, m))

    // const reduced = messages.filter(m => {
    //   return (m.metadata?.origin || m.origin || "no origin") === 'fact_check';
    // });

    // /* If there is more than one message, it is user: "Fact check this resume...", assistant: "...FACT CHECK..."
    //  * which means facts have been generated. */
    // if (reduced.length > 1) {
    //   /* Remove the user message from the UI */
    //   if (reduced[0].role === "user") {
    //     reduced.splice(0, 1);
    //   }
    //   // First message is always 'content'
    //   reduced[0].title = 'Fact Check';
    //   reduced[0].role = 'content';
    //   setHasFacts(true);
    // }

    // return reduced;
  }, [/*setHasFacts*/]);

  const jobResponse = useCallback(async (message: MessageData) => {
    console.log('onJobResponse', message);
    if (message.actions && message.actions.includes("resume_generated")) {
      await resumeConversationRef.current.fetchHistory();
      setHasResume(true);
      setActiveTab(1); // Switch to Resume tab
    }
    if (message.actions && message.actions.includes("facts_checked")) {
      await factsConversationRef.current.fetchHistory();
      setHasFacts(true);
    }
  }, [setHasFacts, setHasResume, setActiveTab]);

  const resumeResponse = useCallback((message: MessageData): void => {
    console.log('onResumeResponse', message);
    setHasFacts(true);
  }, [setHasFacts]);

  const factsResponse = useCallback((message: MessageData): void => {
    console.log('onFactsResponse', message);
  }, []);

  const resetJobDescription = useCallback(() => {
    setHasJobDescription(false);
    setHasResume(false);
    setHasFacts(false);
  }, [setHasJobDescription, setHasResume, setHasFacts]);

  const resetResume = useCallback(() => {
    setHasResume(false);
    setHasFacts(false);
  }, [setHasResume, setHasFacts]);

  const resetFacts = useCallback(() => {
    setHasFacts(false);
  }, [setHasFacts]);

  const renderJobDescriptionView = useCallback((sx: SxProps) => {
    console.log('renderJobDescriptionView');
    const jobDescriptionQuestions = [
      <Box sx={{ display: "flex", flexDirection: "column" }}>
        <ChatQuery prompt="What are the key skills necessary for this position?" tunables={{ enable_tools: false }} submitQuery={handleJobQuery} />
        <ChatQuery prompt="How much should this position pay (accounting for inflation)?" tunables={{ enable_tools: false }} submitQuery={handleJobQuery} />
      </Box>,
    ];

    if (!hasJobDescription) {
      return <Conversation
        ref={jobConversationRef}
        {...{
          type: "job_description",
          actionLabel: "Generate Resume",
          prompt: "Paste a job description, then click Generate...",
          multiline: true,
          resetLabel: `job description${hasFacts ? ", resume, and fact check" : hasResume ? " and resume" : ""}`,
          messageFilter: filterJobDescriptionMessages,
          resetAction: resetJobDescription,
          onResponse: jobResponse,
          sessionId,
          connectionBase,
          setSnack,
          sx,
        }}
      />

    } else {
      return <Conversation
        ref={jobConversationRef}
        {...{
          type: "job_description",
          actionLabel: "Send",
          prompt: "Ask a question about this job description...",
          resetLabel: `job description${hasFacts ? ", resume, and fact check" : hasResume ? " and resume" : ""}`,
          messageFilter: filterJobDescriptionMessages,
          defaultPrompts: jobDescriptionQuestions,
          resetAction: resetJobDescription,
          onResponse: jobResponse,
          sessionId,
          connectionBase,
          setSnack,
          sx,
        }}
      />
    }
  }, [connectionBase, filterJobDescriptionMessages, hasJobDescription, sessionId, setSnack, jobResponse, resetJobDescription, hasFacts, hasResume]);

  /**
   * Renders the resume view with loading indicator
   */
  const renderResumeView = useCallback((sx: SxProps) => {
    const resumeQuestions = [
      <Box sx={{ display: "flex", flexDirection: "column" }}>
        <ChatQuery prompt="Is this resume a good fit for the provided job description?" tunables={{ enable_tools: false }} submitQuery={handleResumeQuery} />
        <ChatQuery prompt="Provide a more concise resume." tunables={{ enable_tools: false }} submitQuery={handleResumeQuery} />
      </Box>,
    ];

    if (!hasFacts) {
      return <Conversation
        ref={resumeConversationRef}
        {...{
          type: "resume",
          actionLabel: "Fact Check",
          defaultQuery: "Fact check the resume.",
          resetLabel: `job description${hasFacts ? ", resume, and fact check" : hasResume ? " and resume" : ""}`,
          messageFilter: filterResumeMessages,
          onResponse: resumeResponse,
          resetAction: resetResume,
          sessionId,
          connectionBase,
          setSnack,
          sx,
        }}
      />
    } else {
      return <Conversation
        ref={resumeConversationRef}
        {...{
          type: "resume",
          actionLabel: "Send",
          prompt: "Ask a question about this job resume...",
          resetLabel: `job description${hasFacts ? ", resume, and fact check" : hasResume ? " and resume" : ""}`,
          messageFilter: filterResumeMessages,
          onResponse: resumeResponse,
          resetAction: resetResume,
          sessionId,
          connectionBase,
          setSnack,
          defaultPrompts: resumeQuestions,
          sx,
        }}
      />
    }
  }, [connectionBase, filterResumeMessages, hasFacts, sessionId, setSnack, resumeResponse, resetResume, hasResume]);

  /**
   * Renders the fact check view
   */
  const renderFactCheckView = useCallback((sx: SxProps) => {
    const factsQuestions = [
      <Box sx={{ display: "flex", flexDirection: "column" }}>
        <ChatQuery prompt="Rewrite the resume to address any discrepancies." tunables={{ enable_tools: false }} submitQuery={handleFactsQuery} />
      </Box>,
    ];

    return <Conversation
      ref={factsConversationRef}
      {...{
        type: "fact_check",
        actionLabel: "Send",
        prompt: "Ask a question about any discrepencies...",
        resetLabel: `job description${hasFacts ? ", resume, and fact check" : hasResume ? " and resume" : ""}`,
        messageFilter: filterFactsMessages,
        defaultPrompts: factsQuestions,
        resetAction: resetFacts,
        onResponse: factsResponse,
        sessionId,
        connectionBase,
        setSnack,
        sx,
      }}
    />
  }, [connectionBase, sessionId, setSnack, factsResponse, filterFactsMessages, resetFacts, hasResume, hasFacts]);

  return (
    <Box sx={{
      p: 0,
      m: 0,
      display: "flex",
      flexGrow: 1,
      margin: "0 auto",
      overflow: "hidden",
      backgroundColor: "#F5F5F5",
      flexDirection: "column",
      maxWidth: "1024px",
    }}
    >
      {/* Tabs */}
      <Tabs
        value={activeTab}
        onChange={handleTabChange}
        variant="fullWidth"
        sx={{ bgcolor: 'background.paper' }}
      >
        <Tab value={0} label="Job Description" />
        {hasResume && <Tab value={1} label="Resume" />}
        {hasFacts && <Tab value={2} label="Fact Check" />}
      </Tabs>

      {/* Document display area */}
      <Box sx={{
        display: 'flex', flexDirection: 'column', flexGrow: 1, p: 0, width: "100%", ...sx,
        overflow: "hidden"
      }}>
        <Box sx={{ display: activeTab === 0 ? "flex" : "none" }}>{renderJobDescriptionView({ height: "calc(100vh - 72px - 48px)" })}</Box>
        <Box sx={{ display: activeTab === 1 ? "flex" : "none" }}>{renderResumeView({ height: "calc(100vh - 72px - 48px)" })}</Box>
        <Box sx={{ display: activeTab === 2 ? "flex" : "none" }}>{renderFactCheckView({ height: "calc(100vh - 72px - 48px)" })}</Box>
      </Box>
    </Box>
  );
};

export type {
  ResumeBuilderProps
};

export {
  ResumeBuilder
};

