import React, { useState, useEffect } from 'react';
import {
  Box,
  Button,
  Grid,
  useMediaQuery,
  Typography,
  Card,
  CardContent,
  List,
  ListItem,
  ListItemText,
  ListItemSecondaryAction,
  IconButton,
  Switch,
  FormControlLabel,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  TextField,
  Chip,
  Divider,
  Paper,
} from '@mui/material';
import { styled } from '@mui/material/styles';
import { 
  CloudUpload,
  Edit,
  Delete,
  Visibility,
  Close,
} from '@mui/icons-material';
import { useTheme } from '@mui/material/styles';

import { useAuth } from "hooks/AuthContext";
import * as Types from 'types/types';
import { BackstoryElementProps } from './BackstoryTab';
import { useAppState } from 'hooks/GlobalContext';

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 DocumentManager = (props: BackstoryElementProps) => {
  const theme = useTheme();
  const { setSnack } = useAppState();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
  const { user, apiClient } = useAuth();
  
  const [documents, setDocuments] = useState<Types.Document[]>([]);
  const [selectedDocument, setSelectedDocument] = useState<Types.Document | null>(null);
  const [documentContent, setDocumentContent] = useState<string>('');
  const [isViewingContent, setIsViewingContent] = useState(false);
  const [editingDocument, setEditingDocument] = useState<Types.Document | null>(null);
  const [editingName, setEditingName] = useState('');
  const [isRenameDialogOpen, setIsRenameDialogOpen] = useState(false);
  
  // Check if user is a candidate
  const candidate = user?.userType === 'candidate' ? user as Types.Candidate : null;

  // Load documents on component mount
  useEffect(() => {
    if (candidate) {
      loadDocuments();
    }
  }, [candidate]);

  const loadDocuments = async () => {
    try {
        const results = await apiClient.getCandidateDocuments();
        setDocuments(results.documents);
    } catch (error) {
        console.error(error);
      setSnack('Failed to load documents', 'error');
    }
  };

  // Handle document upload
  const handleDocumentUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    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 {
        // Upload file (replace with actual API call)
        const controller = apiClient.uploadCandidateDocument(file, { includeInRAG: true, isJobDocument: false });
        const result = await controller.promise;

        setDocuments(prev => [...prev, result.document]);
        setSnack(`Document uploaded: ${file.name}`, 'success');
        
        // Reset file input
        e.target.value = '';
      } catch (error) {
        setSnack('Failed to upload document', 'error');
      }
    }
  };

  // Handle document deletion
  const handleDeleteDocument = async (document: Types.Document) => {
    try {
      // Call API to delete document
      await apiClient.deleteCandidateDocument(document);
      
      setDocuments(prev => prev.filter(doc => doc.id !== document.id));
      setSnack('Document deleted successfully', 'success');
      
      // Close content view if this document was being viewed
      if (selectedDocument?.id === document.id) {
        setIsViewingContent(false);
        setSelectedDocument(null);
        setDocumentContent('');
      }
    } catch (error) {
      setSnack('Failed to delete document', 'error');
    }
  };

  // Handle RAG flag toggle
  const handleRAGToggle = async (document: Types.Document, includeInRAG: boolean) => {
    try {
      document.options = { includeInRAG };
      // Call API to update RAG flag
      await apiClient.updateCandidateDocument(document);
      
      setDocuments(prev => 
        prev.map(doc => 
          doc.id === document.id 
            ? { ...doc, includeInRAG }
            : doc
        )
      );
      setSnack(`Document ${includeInRAG ? 'included in' : 'excluded from'} RAG`, 'success');
    } catch (error) {
      setSnack('Failed to update RAG setting', 'error');
    }
  };

  // Handle document rename
  const handleRenameDocument = async (document: Types.Document, newName: string) => {
    if (!newName.trim()) {
      setSnack('Document name cannot be empty', 'error');
      return;
    }

    try {
      // Call API to rename document
      document.filename = newName
      await apiClient.updateCandidateDocument(document);
      
      setDocuments(prev => 
        prev.map(doc => 
          doc.id === document.id 
            ? { ...doc, filename: newName.trim() }
            : doc
        )
      );
      setSnack('Document renamed successfully', 'success');
      setIsRenameDialogOpen(false);
      setEditingDocument(null);
      setEditingName('');
    } catch (error) {
      setSnack('Failed to rename document', 'error');
    }
  };

  // Handle document content viewing
  const handleViewDocument = async (document: Types.Document) => {
    try {
      setSelectedDocument(document);
      setIsViewingContent(true);
      
      // Call API to get document content
      const result = await apiClient.getCandidateDocumentText(document);
      setDocumentContent(result.content);
    } catch (error) {
      setSnack('Failed to load document content', 'error');
      setIsViewingContent(false);
    }
  };

  // Start rename process
  const startRename = (document: Types.Document, currentName: string) => {
    setEditingDocument(document);
    setEditingName(currentName);
    setIsRenameDialogOpen(true);
  };

  // Format file size
  const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  };

  // Get file type color
  const getFileTypeColor = (type: string): 'primary' | 'secondary' | 'success' | 'warning' => {
    switch (type) {
      case 'pdf': return 'primary';
      case 'docx': return 'secondary';
      case 'txt': return 'success';
      case 'md': return 'warning';
      default: return 'primary';
    }
  };

  if (!candidate) {
    return (<Box>You must be logged in as a candidate to view this content.</Box>);
  }

  return (
    <>
    <Grid container spacing={{ xs: 1, sm: 3 }} sx={{ maxWidth: '100%' }}>
        <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2, width: "100%", verticalAlign: "center" }}>
            <Typography variant={isMobile ? "subtitle2" : "h6"}>
                Documents
            </Typography>
            <Button
                component="label"
                variant="contained"
                startIcon={<CloudUpload />}
                size={isMobile ? "small" : "medium"}>
                Upload Document
                <VisuallyHiddenInput 
                    type="file" 
                    accept=".txt,.md,.docx,.pdf"
                    onChange={handleDocumentUpload}
                />
            </Button>
        </Box>

        <Grid size={{ xs: 12 }}>
            <Card variant="outlined">
                <CardContent sx={{ p: { xs: 1.5, sm: 3 } }}>
                    {documents.length === 0 ? (
                        <Typography variant="body2" color="text.secondary" sx={{ 
                        fontSize: { xs: '0.8rem', sm: '0.875rem' },
                        textAlign: 'center',
                        py: 3
                        }}>
                        No additional documents uploaded
                        </Typography>
                    ) : (
                        <List sx={{ width: '100%' }}>
                        {documents.map((doc, index) => (
                            <React.Fragment key={doc.id}>
                            {index > 0 && <Divider />}
                            <ListItem sx={{ px: 0 }}>
                                <ListItemText
                                primary={
                                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
                                    <Typography variant="body1" sx={{ 
                                        wordBreak: 'break-word',
                                        fontSize: { xs: '0.9rem', sm: '1rem' }
                                    }}>
                                        {doc.filename}
                                    </Typography>
                                    <Chip 
                                        label={doc.type.toUpperCase()} 
                                        size="small" 
                                        color={getFileTypeColor(doc.type)}
                                    />
                                    {doc.options?.includeInRAG && (
                                        <Chip 
                                        label="RAG" 
                                        size="small" 
                                        color="success" 
                                        variant="outlined"
                                        />
                                    )}
                                    </Box>
                                }
                                secondary={
                                    <Box sx={{ mt: 0.5 }}>
                                    <Typography variant="caption" color="text.secondary">
                                        {formatFileSize(doc.size)} • {doc?.uploadDate?.toLocaleDateString()}
                                    </Typography>
                                    <Box sx={{ mt: 1 }}>
                                        <FormControlLabel
                                        control={
                                            <Switch
                                            checked={doc.options?.includeInRAG}
                                            onChange={(e) => handleRAGToggle(doc, e.target.checked)}
                                            size="small"
                                            />
                                        }
                                        label={
                                            <Typography variant="caption">
                                            Include in RAG
                                            </Typography>
                                        }
                                        />
                                    </Box>
                                    </Box>
                                }
                                />
                                <ListItemSecondaryAction>
                                <Box sx={{ display: 'flex', gap: 0.5 }}>
                                    <IconButton
                                    edge="end"
                                    size="small"
                                    onClick={() => handleViewDocument(doc)}
                                    title="View content"
                                    >
                                    <Visibility />
                                    </IconButton>
                                    <IconButton
                                    edge="end"
                                    size="small"
                                    onClick={() => startRename(doc, doc.filename)}
                                    title="Rename"
                                    >
                                    <Edit />
                                    </IconButton>
                                    <IconButton
                                    edge="end"
                                    size="small"
                                    onClick={() => handleDeleteDocument(doc)}
                                    title="Delete"
                                    color="error"
                                    >
                                    <Delete />
                                    </IconButton>
                                </Box>
                                </ListItemSecondaryAction>
                            </ListItem>
                            </React.Fragment>
                        ))}
                        </List>
                    )}
                </CardContent>
            </Card>
        </Grid>

        {/* Document Content Viewer */}
        {isViewingContent && (
          <Grid size={{ xs: 12 }}>
            <Card variant="outlined">
              <CardContent sx={{ p: { xs: 1.5, sm: 3 } }}>
                <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
                  <Typography variant={isMobile ? "subtitle2" : "h6"}>
                    Document Content
                  </Typography>
                  <IconButton
                    size="small"
                    onClick={() => {
                      setIsViewingContent(false);
                      setSelectedDocument(null);
                      setDocumentContent('');
                    }}
                  >
                    <Close />
                  </IconButton>
                </Box>
                <Paper 
                  variant="outlined" 
                  sx={{ 
                    p: 2, 
                    maxHeight: 400, 
                    overflow: 'auto',
                    backgroundColor: 'grey.50'
                  }}
                >
                  <pre style={{ 
                    margin: 0, 
                    fontFamily: 'monospace',
                    fontSize: isMobile ? '0.75rem' : '0.875rem',
                    whiteSpace: 'pre-wrap',
                    wordBreak: 'break-word'
                  }}>
                    {documentContent || 'Loading content...'}
                  </pre>
                </Paper>
              </CardContent>
            </Card>
          </Grid>
        )}

      {/* Rename Dialog */}
      <Dialog 
        open={isRenameDialogOpen} 
        onClose={() => setIsRenameDialogOpen(false)}
        maxWidth="sm"
        fullWidth
      >
        <DialogTitle>Rename Document</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            margin="dense"
            label="Document Name"
            fullWidth
            variant="outlined"
            value={editingName}
            onChange={(e) => setEditingName(e.target.value)}
            onKeyPress={(e) => {
              if (e.key === 'Enter' && editingDocument) {
                handleRenameDocument(editingDocument, editingName);
              }
            }}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setIsRenameDialogOpen(false)}>
            Cancel
          </Button>
          <Button 
            onClick={() => editingDocument && handleRenameDocument(editingDocument, editingName)}
            variant="contained"
            disabled={!editingName.trim()}
          >
            Rename
          </Button>
        </DialogActions>
      </Dialog>
    </Grid>
    </>
  );
};

export { DocumentManager };