import React, { useState, useRef, JSX } from 'react';
import {
  Box,
  Button,
  Typography,
  TextField,
  Grid,
  useTheme,
  useMediaQuery,
  Chip,
  Card,
  CardContent,
  CardHeader,
  LinearProgress,
  Stack,
} from '@mui/material';
import {
  AutoFixHigh,
  Psychology,
  Build,
  CloudUpload,
  Description,
  Business,
  Work,
  CheckCircle,
  Star,
} from '@mui/icons-material';
import { styled } from '@mui/material/styles';
import FileUploadIcon from '@mui/icons-material/FileUpload';

import { useAuth } from 'hooks/AuthContext';
import { useAppState } from 'hooks/GlobalContext';
import { BackstoryElementProps } from './BackstoryTab';

import * as Types from 'types/types';
import { StyledMarkdown } from './StyledMarkdown';
import { JobInfo } from './ui/JobInfo';
import { Scrollable } from './Scrollable';
import { StatusIcon, StatusBox } from 'components/ui/StatusIcon';

const VisuallyHiddenInput = styled('input')({
  clip: 'rect(0 0 0 0)',
  clipPath: 'inset(50%)',
  height: 1,
  overflow: 'hidden',
  position: 'absolute',
  bottom: 0,
  left: 0,
  whiteSpace: 'nowrap',
  width: 1,
});

const UploadBox = styled(Box)(({ theme }) => ({
  border: `2px dashed ${theme.palette.primary.main}`,
  borderRadius:
    (typeof theme.shape.borderRadius === 'string'
      ? parseInt(theme.shape.borderRadius)
      : theme.shape.borderRadius) * 2,
  padding: theme.spacing(4),
  textAlign: 'center',
  backgroundColor: theme.palette.action.hover,
  transition: 'all 0.3s ease',
  cursor: 'pointer',
  '&:hover': {
    backgroundColor: theme.palette.action.selected,
    borderColor: theme.palette.primary.dark,
  },
}));

interface JobCreatorProps extends BackstoryElementProps {
  onSave?: (job: Types.Job) => void;
}
const JobCreator = (props: JobCreatorProps): JSX.Element => {
  const { user, apiClient } = useAuth();
  const { onSave } = props;
  const { setSnack } = useAppState();
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  const [jobDescription, setJobDescription] = useState<string>('');
  const [jobRequirements, setJobRequirements] = useState<Types.JobRequirements | null>(null);
  const [jobTitle, setJobTitle] = useState<string>('');
  const [company, setCompany] = useState<string>('');
  const [summary, setSummary] = useState<string>('');
  const [job, setJob] = useState<Types.Job | null>(null);
  const [jobStatus, setJobStatus] = useState<string>('');
  const [jobStatusType, setJobStatusType] = useState<Types.ApiActivityType | null>(null);
  const [isProcessing, setIsProcessing] = useState<boolean>(false);

  const fileInputRef = useRef<HTMLInputElement>(null);

  const jobStatusHandlers = {
    onStatus: (status: Types.ChatMessageStatus): void => {
      console.log('status:', status.content);
      setJobStatusType(status.activity);
      setJobStatus(status.content);
    },
    onMessage: (jobMessage: Types.JobRequirementsMessage): void => {
      const job: Types.Job = jobMessage.job;
      console.log('onMessage - job', job);
      setJob(job);
      setCompany(job.company || '');
      setJobDescription(job.description);
      setSummary(job.summary || '');
      setJobTitle(job.title || '');
      setJobRequirements(job.requirements || null);
      setJobStatusType(null);
      setJobStatus('');
    },
    onError: (error: Types.ChatMessageError): void => {
      console.log('onError', error);
      setSnack(error.content, 'error');
      setIsProcessing(false);
    },
    onComplete: (): void => {
      setJobStatusType(null);
      setJobStatus('');
      setIsProcessing(false);
    },
  };

  const handleJobUpload = async (e: React.ChangeEvent<HTMLInputElement>): Promise<void> => {
    if (e.target.files && e.target.files[0]) {
      const file = e.target.files[0];
      const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
      let docType: Types.DocumentType | null = null;
      switch (fileExtension.substring(1)) {
        case 'pdf':
          docType = 'pdf';
          break;
        case 'docx':
          docType = 'docx';
          break;
        case 'md':
          docType = 'markdown';
          break;
        case 'txt':
          docType = 'txt';
          break;
      }

      if (!docType) {
        setSnack('Invalid file type. Please upload .txt, .md, .docx, or .pdf files only.', 'error');
        return;
      }

      try {
        setIsProcessing(true);
        setJobDescription('');
        setJobTitle('');
        setJobRequirements(null);
        setSummary('');
        const controller = apiClient.createJobFromFile(file, jobStatusHandlers);
        const job = await controller.promise;
        if (!job) {
          return;
        }
        console.log(`Job id: ${job.id}`);
        e.target.value = '';
      } catch (error) {
        console.error(error);
        setSnack('Failed to upload document', 'error');
        setIsProcessing(false);
      }
    }
  };

  const handleUploadClick = (): void => {
    fileInputRef.current?.click();
  };

  const renderRequirementSection = (
    title: string,
    items: string[] | undefined,
    icon: JSX.Element,
    required = false
  ): JSX.Element => {
    if (!items || items.length === 0) return <></>;

    return (
      <Box sx={{ mb: 3 }}>
        <Box sx={{ display: 'flex', alignItems: 'center', mb: 1.5 }}>
          {icon}
          <Typography variant="subtitle1" sx={{ ml: 1, fontWeight: 600 }}>
            {title}
          </Typography>
          {required && <Chip label="Required" size="small" color="error" sx={{ ml: 1 }} />}
        </Box>
        <Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap>
          {items.map((item, index) => (
            <Chip key={index} label={item} variant="outlined" size="small" sx={{ mb: 1 }} />
          ))}
        </Stack>
      </Box>
    );
  };

  const renderJobRequirements = (): JSX.Element => {
    if (!jobRequirements) return <></>;

    return (
      <Card elevation={2} sx={{ mt: 3 }}>
        <CardHeader
          title="Job Requirements Analysis"
          avatar={<CheckCircle color="success" />}
          sx={{ pb: 1 }}
        />
        <CardContent sx={{ pt: 0 }}>
          {renderRequirementSection(
            'Technical Skills (Required)',
            jobRequirements.technicalSkills.required,
            <Build color="primary" />,
            true
          )}
          {renderRequirementSection(
            'Technical Skills (Preferred)',
            jobRequirements.technicalSkills.preferred,
            <Build color="action" />
          )}
          {renderRequirementSection(
            'Experience Requirements (Required)',
            jobRequirements.experienceRequirements.required,
            <Work color="primary" />,
            true
          )}
          {renderRequirementSection(
            'Experience Requirements (Preferred)',
            jobRequirements.experienceRequirements.preferred,
            <Work color="action" />
          )}
          {renderRequirementSection(
            'Soft Skills',
            jobRequirements.softSkills,
            <Psychology color="secondary" />
          )}
          {renderRequirementSection(
            'Experience',
            jobRequirements.experience,
            <Star color="warning" />
          )}
          {renderRequirementSection(
            'Education',
            jobRequirements.education,
            <Description color="info" />
          )}
          {renderRequirementSection(
            'Certifications',
            jobRequirements.certifications,
            <CheckCircle color="success" />
          )}
          {renderRequirementSection(
            'Preferred Attributes',
            jobRequirements.preferredAttributes,
            <Star color="secondary" />
          )}
        </CardContent>
      </Card>
    );
  };

  const handleSave = async (): Promise<void> => {
    const newJob: Types.Job = {
      ownerId: user?.id || '',
      ownerType: 'candidate',
      description: jobDescription,
      company: company,
      summary: summary,
      title: jobTitle,
      requirements: jobRequirements || undefined,
      createdAt: new Date(),
      updatedAt: new Date(),
    };
    setIsProcessing(true);
    const job = await apiClient.createJob(newJob);
    setIsProcessing(false);
    if (!job) {
      setSnack('Failed to save job', 'error');
      return;
    }
    onSave && onSave(job);
  };

  const handleExtractRequirements = async (): Promise<void> => {
    try {
      setIsProcessing(true);
      const controller = apiClient.createJobFromDescription(jobDescription, jobStatusHandlers);
      const job = await controller.promise;
      if (!job) {
        setIsProcessing(false);
        return;
      }
      console.log(`Job id: ${job.id}`);
    } catch (error) {
      console.error(error);
      setSnack('Failed to upload document', 'error');
      setIsProcessing(false);
    }
    setIsProcessing(false);
  };

  const renderJobCreation = (): JSX.Element => {
    return (
      <Box
        sx={{
          width: '100%',
          p: 1,
        }}
      >
        {/* Upload Section */}
        <Card elevation={3} sx={{ mb: 4 }}>
          <CardHeader
            title="Job Information"
            subheader="Upload a job description or enter details manually"
            avatar={<Work color="primary" />}
          />
          <CardContent>
            <Grid container spacing={3}>
              <Grid size={{ xs: 12, md: 6 }}>
                <Typography
                  variant="h6"
                  gutterBottom
                  sx={{ display: 'flex', alignItems: 'center' }}
                >
                  <CloudUpload sx={{ mr: 1 }} />
                  Upload Job Description
                </Typography>
                <UploadBox onClick={handleUploadClick}>
                  <CloudUpload sx={{ fontSize: 48, color: 'primary.main', mb: 2 }} />
                  <Typography variant="h6" gutterBottom>
                    Drop your job description here
                  </Typography>
                  <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
                    Supported formats: PDF, DOCX, TXT, MD
                  </Typography>
                  <Button
                    variant="contained"
                    startIcon={<FileUploadIcon />}
                    disabled={isProcessing}
                    // onClick={handleUploadClick}
                  >
                    Choose File
                  </Button>
                </UploadBox>
                <VisuallyHiddenInput
                  ref={fileInputRef}
                  type="file"
                  accept=".txt,.md,.docx,.pdf"
                  onChange={handleJobUpload}
                />
              </Grid>

              <Grid size={{ xs: 12, md: 6 }}>
                <Typography
                  variant="h6"
                  gutterBottom
                  sx={{ display: 'flex', alignItems: 'center' }}
                >
                  <Description sx={{ mr: 1 }} />
                  Or Enter Manually
                </Typography>
                <TextField
                  fullWidth
                  multiline
                  rows={isMobile ? 8 : 12}
                  placeholder="Paste or type the job description here..."
                  variant="outlined"
                  value={jobDescription}
                  onChange={(e): void => {
                    setJobDescription(e.target.value);
                  }}
                  disabled={isProcessing}
                  sx={{ mb: 2 }}
                />
                {jobRequirements === null && jobDescription && (
                  <Button
                    variant="outlined"
                    onClick={handleExtractRequirements}
                    startIcon={<AutoFixHigh />}
                    disabled={isProcessing}
                    fullWidth={isMobile}
                  >
                    Extract Requirements
                  </Button>
                )}
              </Grid>
            </Grid>

            {(jobStatus || isProcessing) && (
              <Box sx={{ mt: 3 }}>
                <StatusBox>
                  {jobStatusType && <StatusIcon type={jobStatusType} />}
                  <Typography variant="body2" sx={{ ml: 1 }}>
                    {jobStatus || 'Processing...'}
                  </Typography>
                </StatusBox>
                {isProcessing && <LinearProgress sx={{ mt: 1 }} />}
              </Box>
            )}
          </CardContent>
        </Card>

        {/* Job Details Section */}
        <Card elevation={3} sx={{ mb: 4 }}>
          <CardHeader
            title="Job Details"
            subheader="Enter specific information about the position"
            avatar={<Business color="primary" />}
          />
          <CardContent>
            <Grid container spacing={3}>
              <Grid size={{ xs: 12, md: 6 }}>
                <TextField
                  fullWidth
                  label="Job Title"
                  variant="outlined"
                  value={jobTitle}
                  onChange={(e): void => {
                    setJobTitle(e.target.value);
                  }}
                  required
                  disabled={isProcessing}
                  InputProps={{
                    startAdornment: <Work sx={{ mr: 1, color: 'text.secondary' }} />,
                  }}
                />
              </Grid>

              <Grid size={{ xs: 12, md: 6 }}>
                <TextField
                  fullWidth
                  label="Company"
                  variant="outlined"
                  value={company}
                  onChange={(e): void => {
                    setCompany(e.target.value);
                  }}
                  required
                  disabled={isProcessing}
                  InputProps={{
                    startAdornment: <Business sx={{ mr: 1, color: 'text.secondary' }} />,
                  }}
                />
              </Grid>

              {/* <Grid size={{ xs: 12, md: 6 }}>
                  <TextField
                    fullWidth
                    label="Job Location"
                    variant="outlined"
                    value={jobLocation}
                    onChange={(e) => setJobLocation(e.target.value)}
                    disabled={isProcessing}
                    InputProps={{
                      startAdornment: <LocationOn sx={{ mr: 1, color: 'text.secondary' }} />
                    }}
                  />
                </Grid> */}
            </Grid>
          </CardContent>
        </Card>

        {/* Job Summary */}
        {summary !== '' && (
          <Card elevation={2} sx={{ mt: 3 }}>
            <CardHeader
              title="Job Summary"
              avatar={<CheckCircle color="success" />}
              sx={{ pb: 1 }}
            />
            <CardContent sx={{ pt: 0 }}>{summary}</CardContent>
          </Card>
        )}

        {/* Requirements Display */}
        {renderJobRequirements()}
      </Box>
    );
  };

  return (
    <Box
      className="JobManagement"
      sx={{
        background: 'white',
        p: 0,
        width: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {job === null && renderJobCreation()}
      {job && (
        <Box
          sx={{
            display: 'flex',
            flexDirection: 'column',
            height: '100%' /* Restrict to main-container's height */,
            width: '100%',
            minHeight: 0 /* Prevent flex overflow */,
            maxHeight: 'min-content',
            position: 'relative',
          }}
        >
          <Box
            sx={{
              display: 'flex',
              flexDirection: 'row',
              flexGrow: 1,
              gap: 1,
              height: '100%' /* Restrict to main-container's height */,
              width: '100%',
              minHeight: 0 /* Prevent flex overflow */,
              maxHeight: 'min-content',
              '& > *:not(.Scrollable)': {
                flexShrink: 0 /* Prevent shrinking */,
              },
              position: 'relative',
            }}
          >
            <Scrollable
              sx={{
                display: 'flex',
                flexGrow: 1,
                position: 'relative',
                maxHeight: '30rem',
              }}
            >
              <JobInfo job={job} />
            </Scrollable>
            <Scrollable
              sx={{
                display: 'flex',
                flexGrow: 1,
                position: 'relative',
                maxHeight: '30rem',
              }}
            >
              <StyledMarkdown content={job.description} />
            </Scrollable>
          </Box>
          <Box sx={{ display: 'flex', gap: 2, alignItems: 'flex-end' }}>
            <Button
              variant="contained"
              onClick={handleSave}
              disabled={!jobTitle || !company || !jobDescription || isProcessing}
              fullWidth={isMobile}
              size="large"
              startIcon={<CheckCircle />}
            >
              Save Job
            </Button>
          </Box>
        </Box>
      )}
    </Box>
  );
};

export { JobCreator };
