import React, { useState, useEffect } from 'react';
import { 
  Box, 
  Typography, 
  Paper, 
  Accordion, 
  AccordionSummary, 
  AccordionDetails,
  CircularProgress,
  Grid,
  Chip,
  Divider,
  Card,
  CardContent,
  useTheme,
  LinearProgress,
  useMediaQuery,
  Button
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import ErrorIcon from '@mui/icons-material/Error';
import PendingIcon from '@mui/icons-material/Pending';
import WarningIcon from '@mui/icons-material/Warning';
import { Candidate, ChatMessage, ChatMessageError, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, JobRequirements, SkillMatch } from 'types/types';
import { useAuth } from 'hooks/AuthContext';
import { BackstoryPageProps } from './BackstoryTab';
import { toCamelCase } from 'types/conversion';
import { Job } from 'types/types';
import { StyledMarkdown } from './StyledMarkdown';
import { Scrollable } from './Scrollable';
import { start } from 'repl';
import { TypesElement } from '@uiw/react-json-view';

interface JobAnalysisProps extends BackstoryPageProps {
  job: Job;
  candidate: Candidate;
}

const defaultMessage: ChatMessage = {
  status: "done", type: "text", sessionId: "", timestamp: new Date(), content: "", role: "assistant"
};

const JobMatchAnalysis: React.FC<JobAnalysisProps> = (props: JobAnalysisProps) => {
  const {
    job,
    candidate,
    setSnack,
    submitQuery
  } = props
  const { apiClient } = useAuth();
  const backstoryProps = { setSnack, submitQuery };
  const theme = useTheme();
  const [requirements, setRequirements] = useState<{ requirement: string, domain: string }[]>([]);
  const [skillMatches, setSkillMatches] = useState<SkillMatch[]>([]);
  const [creatingSession, setCreatingSession] = useState<boolean>(false);
  const [loadingRequirements, setLoadingRequirements] = useState<boolean>(false);
  const [expanded, setExpanded] = useState<string | false>(false);
  const [overallScore, setOverallScore] = useState<number>(0);
  const [requirementsSession, setRequirementsSession] = useState<ChatSession | null>(null);
  const [statusMessage, setStatusMessage] = useState<ChatMessage | null>(null);
  const [startAnalysis, setStartAnalysis] = useState<boolean>(false);
  const [analyzing, setAnalyzing] = useState<boolean>(false);

  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  // Handle accordion expansion
  const handleAccordionChange = (panel: string) => (event: React.SyntheticEvent, isExpanded: boolean) => {
    setExpanded(isExpanded ? panel : false);
  };

  const initializeRequirements = (job: Job) => {
    if (!job || !job.requirements) {
      return;
    }
    const requirements: { requirement: string, domain: string }[] = [];
    if (job.requirements?.technicalSkills) {
      job.requirements.technicalSkills.required?.forEach(req => requirements.push({ requirement: req, domain: 'Technical Skills (required)' }));
      job.requirements.technicalSkills.preferred?.forEach(req => requirements.push({ requirement: req, domain: 'Technical Skills (preferred)' }));
    }
    if (job.requirements?.experienceRequirements) {
      job.requirements.experienceRequirements.required?.forEach(req => requirements.push({ requirement: req, domain: 'Experience (required)' }));
      job.requirements.experienceRequirements.preferred?.forEach(req => requirements.push({ requirement: req, domain: 'Experience (preferred)' }));
    }
    if (job.requirements?.softSkills) {
      job.requirements.softSkills.forEach(req => requirements.push({ requirement: req, domain: 'Soft Skills' }));
    }
    if (job.requirements?.experience) {
      job.requirements.experience.forEach(req => requirements.push({ requirement: req, domain: 'Experience' }));
    }
    if (job.requirements?.education) {
      job.requirements.education.forEach(req => requirements.push({ requirement: req, domain: 'Education' }));
    }
    if (job.requirements?.certifications) {
      job.requirements.certifications.forEach(req => requirements.push({ requirement: req, domain: 'Certifications' }));
    }
    if (job.requirements?.preferredAttributes) {
      job.requirements.preferredAttributes.forEach(req => requirements.push({ requirement: req, domain: 'Preferred Attributes' }));
    }

    const initialSkillMatches = requirements.map(req => ({
      requirement: req.requirement,
      domain: req.domain,
      status: 'waiting' as const,
      matchScore: 0,
      assessment: '',
      description: '',
      citations: []
    }));

    setRequirements(requirements);
    setSkillMatches(initialSkillMatches);
    setStatusMessage(null);
    setLoadingRequirements(false);
    setOverallScore(0);
  }

  useEffect(() => {
    initializeRequirements(job);
  }, [job]);

  // Fetch match data for each requirement
  useEffect(() => {
    if (!startAnalysis || analyzing || !job.requirements) {
      return;
    }

    const fetchMatchData = async () => {
      if (requirements.length === 0) return;
      
      // Process requirements one by one
      for (let i = 0; i < requirements.length; i++) {
        try {
          setSkillMatches(prev => {
            const updated = [...prev];
            updated[i] = { ...updated[i], status: 'pending' };
            return updated;
          });

          const result: any = await apiClient.candidateMatchForRequirement(candidate.id || '', requirements[i].requirement);
          const skillMatch = result.skillMatch;
          let matchScore: number = 0;
          switch (skillMatch.evidenceStrength) {
            case "STRONG": matchScore = 100; break;
            case "MODERATE": matchScore = 75; break;
            case "WEAK": matchScore = 50; break;
            case "NONE": matchScore = 0; break;
          }
          if (skillMatch.evidenceStrength == "NONE" && skillMatch.citations && skillMatch.citations.length > 3) {
            matchScore = Math.min(skillMatch.citations.length * 8, 40);
          }
          const match: SkillMatch = {
            status: "complete",
            matchScore,
            domain: requirements[i].domain,
            requirement: skillMatch.skill,
            assessment: skillMatch.assessment,
            citations: skillMatch.evidenceDetails.map((evidence: any) => { return { source: evidence.source, text: evidence.quote, context: evidence.context } }),
            description: skillMatch.description
          };
          setSkillMatches(prev => {
            const updated = [...prev];
            updated[i] = match;
            return updated;
          });

          // Update overall score
          setSkillMatches(current => {
            const completedMatches = current.filter(match => match.status === 'complete');
            if (completedMatches.length > 0) {
              const newOverallScore = completedMatches.reduce((sum, match) => sum + match.matchScore, 0) / completedMatches.length;
              setOverallScore(newOverallScore);
            }
            return current;
          });
        } catch (error) {
          console.error(`Error fetching match for requirement ${requirements[i]}:`, error);
          setSkillMatches(prev => {
            const updated = [...prev];
            updated[i] = {
              ...updated[i],
              status: 'error',
              assessment: 'Failed to analyze this requirement.'
            };
            return updated;
          });
        }
      }
    };
    
    setAnalyzing(true);
    fetchMatchData().then(() => { setAnalyzing(false); setStartAnalysis(false) });
  }, [job, startAnalysis, analyzing, requirements, loadingRequirements]);

  // Get color based on match score
  const getMatchColor = (score: number): string => {
    if (score >= 80) return theme.palette.success.main;
    if (score >= 60) return theme.palette.info.main;
    if (score >= 40) return theme.palette.warning.main;
    return theme.palette.error.main;
  };

  // Get icon based on status
  const getStatusIcon = (status: string, score: number) => {
    if (status === 'pending' || status === 'waiting') return <PendingIcon />;
    if (status === 'error') return <ErrorIcon color="error" />;
    if (score >= 70) return <CheckCircleIcon color="success" />;
    if (score >= 40) return <WarningIcon color="warning" />;
    return <ErrorIcon color="error" />;
  };

  const beginAnalysis = () => {
    initializeRequirements(job);
    setStartAnalysis(true);
  };

  return (
    <Box>
      <Paper elevation={3} sx={{ p: 3, mb: 4 }}>
        <Grid container spacing={2}>
          <Box sx={{ display: "flex", flexDirection: isMobile ? "column" : "row" }}>
            <Grid size={{ xs: 12, md: 6 }} sx={{ display: "flex", flexGrow: 1, flexDirection: "column" }}>
              <Typography variant="h6" component="h2">
                Company:
              </Typography>
              <Typography variant="body1" component="h2">
                {job.company || "N/A"}
              </Typography>

              <Typography variant="h6" component="h2">
                Job Title:
              </Typography>
              <Typography variant="body1" component="h2">
                {job.title || "N/A"}
              </Typography>

              <Typography variant="h6" component="h2">
                Backstory Generated Job Summary:
              </Typography>
              <Typography variant="body1" component="h2">
                {job.summary || "N/A"}
              </Typography>

              <Typography variant="caption">Job ID: {job.id}</Typography>
            </Grid>

            <Grid size={{ xs: 12, md: 6 }} sx={{ display: "flex", flexShrink: 1, flexDirection: "column" }}>
              <Typography variant="h6" component="h2">
                Original Job Description:
              </Typography>
              <Paper sx={{ p: 2, maxHeight: "22rem" }}>
                <Scrollable sx={{ display: "flex", maxHeight: "100%" }}>
                  <StyledMarkdown content={job.description} {...backstoryProps} />
                </Scrollable>
              </Paper>
            </Grid>
          </Box>
          
          <Grid size={{ xs: 12 }} sx={{ mt: 2 }}>
            <Box sx={{ display: 'flex', alignItems: 'center', mb: 2, gap: 1 }}>
              {<Button disabled={analyzing || startAnalysis} onClick={beginAnalysis} variant="contained">Start Analysis</Button>}
              {overallScore !== 0 && <>
              <Typography variant="h5" component="h2" sx={{ mr: 2 }}>
                Overall Match:
              </Typography>
              <Box sx={{ 
                position: 'relative', 
                display: 'inline-flex', 
                mr: 2 
              }}>
                <CircularProgress 
                  variant="determinate" 
                  value={overallScore} 
                  size={60} 
                  thickness={5} 
                  sx={{ 
                    color: getMatchColor(overallScore),
                  }} 
                />
                <Box
                  sx={{
                    top: 0,
                    left: 0,
                    bottom: 0,
                    right: 0,
                    position: 'absolute',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                  }}
                >
                  <Typography variant="caption" component="div" sx={{ fontWeight: 'bold' }}>
                    {`${Math.round(overallScore)}%`}
                  </Typography>
                </Box>
              </Box>
              <Chip 
                label={
                  overallScore >= 80 ? "Excellent Match" :
                  overallScore >= 60 ? "Good Match" :
                  overallScore >= 40 ? "Partial Match" : "Low Match"
                } 
                sx={{ 
                  bgcolor: getMatchColor(overallScore),
                  color: 'white',
                  fontWeight: 'bold'
                }} 
              />
              </>}
            </Box>
          </Grid>
        </Grid>
      </Paper>

      {loadingRequirements ? (
        <Box sx={{ display: 'flex', justifyContent: 'center', p: 4 }}>
          <CircularProgress />
          <Typography variant="h6" sx={{ ml: 2 }}>
            Analyzing job requirements...
          </Typography>
        </Box>
      ) : (
        <Box>
          <Typography variant="h5" component="h2" gutterBottom>
            Requirements Analysis
          </Typography>
          
          {skillMatches.map((match, index) => (
            <Accordion 
              key={index}
              expanded={expanded === `panel${index}`}
              onChange={handleAccordionChange(`panel${index}`)}
              sx={{ 
                mb: 2,
                border: '1px solid',
                borderColor: match.status === 'complete' 
                  ? getMatchColor(match.matchScore) 
                  : theme.palette.divider
              }}
            >
              <AccordionSummary
                expandIcon={<ExpandMoreIcon />}
                aria-controls={`panel${index}bh-content`}
                id={`panel${index}bh-header`}
                sx={{
                  bgcolor: match.status === 'complete' 
                    ? `${getMatchColor(match.matchScore)}22` // Add transparency
                    : 'inherit'
                }}
              >
                <Box sx={{ 
                  display: 'flex', 
                  alignItems: 'center', 
                  width: '100%', 
                  justifyContent: 'space-between' 
                }}>
                  <Box sx={{ display: 'flex', alignItems: 'center' }}>
                    {getStatusIcon(match.status, match.matchScore)}
                    <Box sx={{ display: "flex", flexDirection: "column", gap: 0, p: 0, m: 0 }}>
                      <Typography sx={{ ml: 1, mb: 0, fontWeight: 'medium', marginBottom: "0px !important" }}>
                      {match.requirement}
                    </Typography>
                      <Typography variant="caption" sx={{ ml: 1, fontWeight: 'light' }}>
                        {match.domain}
                      </Typography>
                    </Box>
                  </Box>
                  
                  {match.status === 'complete' ? (
                    <Chip 
                      label={`${match.matchScore}% Match`}
                      size="small"
                      sx={{ 
                        bgcolor: getMatchColor(match.matchScore),
                        color: 'white',
                        minWidth: 90
                      }} 
                    />
                  ) : match.status === 'waiting' ? (
                    <Chip
                      label="Waiting..."
                      size="small"
                      sx={{ bgcolor: "rgb(189, 173, 85)", color: 'white', minWidth: 90 }}
                    />
                  ) : match.status === 'pending' ? (
                    <Chip 
                      label="Analyzing..." 
                      size="small"
                      sx={{ bgcolor: theme.palette.grey[400], color: 'white', minWidth: 90 }} 
                    />
                  ) : (
                    <Chip 
                      label="Error" 
                      size="small"
                      sx={{ bgcolor: theme.palette.error.main, color: 'white', minWidth: 90 }} 
                    />
                  )}
                </Box>
              </AccordionSummary>
              
              <AccordionDetails>
                {match.status === 'pending' ? (
                  <Box sx={{ width: '100%', p: 2 }}>
                    <LinearProgress />
                    <Typography sx={{ mt: 2 }}>
                      Analyzing candidate's match for this requirement...
                    </Typography>
                  </Box>
                ) : match.status === 'error' ? (
                  <Typography color="error">
                    {match.assessment || "An error occurred while analyzing this requirement."}
                  </Typography>
                ) : (
                  <Box>
                    <Typography variant="h6" gutterBottom>
                          Assessment
                    </Typography>
                    
                    <Typography paragraph sx={{ mb: 3 }}>
                      {match.assessment}
                    </Typography>
                    
                    <Typography variant="h6" gutterBottom>
                          Supporting Evidence
                        </Typography>
                        {match.citations && match.citations.length > 0 ? (
                      match.citations.map((citation, citIndex) => (
                        <Card 
                          key={citIndex} 
                          variant="outlined" 
                          sx={{ 
                            mb: 2,
                            borderLeft: '4px solid',
                            borderColor: theme.palette.primary.main,
                          }}
                        >
                          <CardContent>
                            <Typography variant="body1" component="div" sx={{ mb: 1, fontStyle: 'italic' }}>
                              "{citation.text}"
                            </Typography>
                            <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', flexDirection: "column" }}>
                              <Typography variant="body2" color="text.secondary">
                                Relevance: {citation.context}
                              </Typography>
                              <Typography variant="caption" color="text.secondary">
                                Source: {citation.source}
                              </Typography>
                              {/* <Chip
                                size="small"
                                label={`Relevance: ${citation.relevance}%`}
                                sx={{
                                  bgcolor: theme.palette.grey[200],
                                }}
                              /> */}
                            </Box>
                          </CardContent>
                        </Card>
                      ))
                    ) : (
                      <Typography color="text.secondary">
                        No specific evidence found in candidate's profile.
                      </Typography>
                    )}
                        <Typography variant="h6" gutterBottom>
                          Skill description
                        </Typography>
                        <Typography paragraph>
                          {match.description}
                        </Typography>

                  </Box>
                )}
              </AccordionDetails>
            </Accordion>
          ))}
        </Box>
      )}
    </Box>
  );
};

export { JobMatchAnalysis };