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,
  EvidenceDetail,
  JobRequirements,
  SkillAssessment,
  SkillStatus,
} from 'types/types';
import { useAuth } from 'hooks/AuthContext';
import { BackstoryPageProps } from './BackstoryTab';
import { Job } from 'types/types';
import { StyledMarkdown } from './StyledMarkdown';
import { Scrollable } from './Scrollable';
import { useAppState } from 'hooks/GlobalContext';
import * as Types from 'types/types';
import JsonView from '@uiw/react-json-view';
import { VectorVisualizer } from './VectorVisualizer';
import { JobInfo } from './ui/JobInfo';

interface JobAnalysisProps extends BackstoryPageProps {
  job: Job;
  candidate: Candidate;
  variant?: 'small' | 'normal';
  onAnalysisComplete: (skills: SkillAssessment[]) => void;
}

const defaultMessage: ChatMessage = {
  status: 'done',
  type: 'text',
  sessionId: '',
  timestamp: new Date(),
  content: '',
  role: 'assistant',
  metadata: null as any,
};

interface SkillMatch extends SkillAssessment {
  domain: string;
  status: SkillStatus;
  matchScore: number;
}

const JobMatchAnalysis: React.FC<JobAnalysisProps> = (props: JobAnalysisProps) => {
  const { job, candidate, onAnalysisComplete, variant = 'normal' } = props;
  const { apiClient } = useAuth();
  const { setSnack } = useAppState();
  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 [matchStatus, setMatchStatus] = useState<string>('');
  const [matchStatusType, setMatchStatusType] = useState<Types.ApiActivityType | null>(null);

  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: SkillMatch[] = requirements.map(req => ({
      skill: req.requirement,
      skillModified: req.requirement,
      candidateId: candidate.id || '',
      domain: req.domain,
      status: 'waiting' as const,
      assessment: '',
      description: '',
      evidenceFound: false,
      evidenceStrength: 'none',
      evidenceDetails: [],
      matchScore: 0,
    }));

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

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

  const skillMatchHandlers = {
    onStatus: (status: Types.ChatMessageStatus) => {
      setMatchStatusType(status.activity);
      setMatchStatus(status.content.toLowerCase());
    },
  };

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

    const fetchMatchData = async (skills: SkillAssessment[]) => {
      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 request: any = await apiClient.candidateMatchForRequirement(
            candidate.id || '',
            requirements[i].requirement,
            skillMatchHandlers
          );
          const result = await request.promise;
          const skillMatch = result.skillAssessment;
          skills.push(skillMatch);
          setMatchStatus('');
          let matchScore = 0;
          switch (skillMatch.evidenceStrength.toUpperCase()) {
            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 = {
            ...skillMatch,
            status: 'complete',
            matchScore,
            domain: requirements[i].domain,
          };
          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);
    const skills: SkillAssessment[] = [];
    fetchMatchData(skills).then(() => {
      setAnalyzing(false);
      setStartAnalysis(false);
      onAnalysisComplete && onAnalysisComplete(skills);
    });
  }, [job, onAnalysisComplete, 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 sx={{ display: 'flex', flexDirection: 'column', m: 0, p: 0 }}>
      {variant !== 'small' && <JobInfo job={job} variant="normal" />}

      <Box
        sx={{
          display: 'flex',
          flexDirection: 'row',
          alignItems: 'center',
          mb: isMobile ? 1 : 2,
          gap: 1,
          justifyContent: 'space-between',
        }}
      >
        <Box
          sx={{
            display: 'flex',
            flexDirection: isMobile ? 'column' : 'row',
            flexGrow: 1,
            gap: 1,
          }}
        >
          {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>
        <Button
          sx={{ marginLeft: 'auto' }}
          disabled={analyzing || startAnalysis}
          onClick={beginAnalysis}
          variant="contained"
        >
          {analyzing ? 'Assessment in Progress' : 'Start Skill Assessment'}
        </Button>
      </Box>

      {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.skill}
                      </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... {matchStatus}
                    </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.evidenceDetails && match.evidenceDetails.length > 0 ? (
                      match.evidenceDetails.map((evidence, evndex) => (
                        <Card
                          key={evndex}
                          variant="outlined"
                          sx={{
                            mb: 2,
                            borderLeft: '4px solid',
                            borderColor: theme.palette.primary.main,
                          }}
                        >
                          <CardContent>
                            <Typography
                              variant="body1"
                              component="div"
                              sx={{ mb: 1, fontStyle: 'italic' }}
                            >
                              "{evidence.quote}"
                            </Typography>
                            <Box
                              sx={{
                                display: 'flex',
                                justifyContent: 'space-between',
                                alignItems: 'flex-start',
                                flexDirection: 'column',
                              }}
                            >
                              <Typography variant="body2" color="text.secondary">
                                Relevance: {evidence.context}
                              </Typography>
                              <Typography variant="caption" color="text.secondary">
                                Source: {evidence.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>
                    {/* { match.ragResults && match.ragResults.length !== 0 && <>
                          <Typography variant="h6" gutterBottom>
                            RAG Information
                          </Typography>
                          <VectorVisualizer inline rag={match.ragResults[0]} />
                        </>
                        } */}
                  </Box>
                )}
              </AccordionDetails>
            </Accordion>
          ))}
        </Box>
      )}
    </Box>
  );
};

export { JobMatchAnalysis };
