import React, { useState, useEffect } from 'react';
import {
  Box,
  Typography,
  Card,
  CardContent,
  Button,
  Chip,
  IconButton,
  TextField,
  InputAdornment,
  Stack,
  CircularProgress,
  Alert,
  Pagination,
  FormControl,
  InputLabel,
  Select,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Checkbox,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Tooltip,
  MenuItem,
  Breadcrumbs,
  Link,
} from '@mui/material';
import {
  Search as SearchIcon,
  FilterList as FilterIcon,
  Delete as DeleteIcon,
  Block as BlockIcon,
  Refresh as RefreshIcon,
  Folder as FolderIcon,
  Cloud as CloudIcon,
  Computer as ComputerIcon,
  Storage as StorageIcon,
  CalendarToday as DateIcon,
  ArrowBack as ArrowBackIcon,
  RestoreFromTrash as RestoreFromTrashIcon,
} from '@mui/icons-material';
import { format, formatDistanceToNow } from 'date-fns';
import { useNotifications } from '../contexts/NotificationContext';
import { useNavigate, useSearchParams } from 'react-router-dom';

interface IgnoredFile {
  id: string;
  file_hash: string;
  filename: string;
  original_filename: string;
  file_path: string;
  file_size: number;
  mime_type: string;
  source_type?: string;
  source_path?: string;
  source_identifier?: string;
  ignored_at: string;
  ignored_by: string;
  ignored_by_username?: string;
  reason?: string;
  created_at: string;
}

interface IgnoredFilesStats {
  total_ignored_files: number;
  by_source_type: Array<{
    source_type?: string;
    count: number;
    total_size_bytes: number;
  }>;
  total_size_bytes: number;
  most_recent_ignored_at?: string;
}

const IgnoredFilesPage: React.FC = () => {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const [ignoredFiles, setIgnoredFiles] = useState<IgnoredFile[]>([]);
  const [stats, setStats] = useState<IgnoredFilesStats | null>(null);
  const [sources, setSources] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [searchTerm, setSearchTerm] = useState('');
  const [sourceTypeFilter, setSourceTypeFilter] = useState('');
  const [selectedFiles, setSelectedFiles] = useState<Set<string>>(new Set());
  const [bulkDeleteDialog, setBulkDeleteDialog] = useState(false);
  const [deletingFiles, setDeletingFiles] = useState(false);
  const { addNotification } = useNotifications();

  // URL parameters for filtering
  const sourceTypeParam = searchParams.get('sourceType');
  const sourceNameParam = searchParams.get('sourceName');
  const sourceIdParam = searchParams.get('sourceId');

  const pageSize = 25;

  const fetchIgnoredFiles = async () => {
    setLoading(true);
    setError(null);
    
    try {
      const token = localStorage.getItem('token');
      if (!token) {
        throw new Error('No authentication token found');
      }

      const params = new URLSearchParams({
        limit: pageSize.toString(),
        offset: ((page - 1) * pageSize).toString(),
      });

      if (searchTerm) {
        params.append('filename', searchTerm);
      }

      if (sourceTypeFilter) {
        params.append('source_type', sourceTypeFilter);
      }

      if (sourceIdParam) {
        params.append('source_identifier', sourceIdParam);
      }

      const response = await fetch(`/api/ignored-files?${params}`, {
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        throw new Error(`Failed to fetch ignored files: ${response.statusText}`);
      }

      const data = await response.json();
      setIgnoredFiles(data.ignored_files);
      setTotalPages(Math.ceil(data.total / pageSize));
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load ignored files');
      console.error('Error fetching ignored files:', err);
    } finally {
      setLoading(false);
    }
  };

  const fetchStats = async () => {
    try {
      const token = localStorage.getItem('token');
      if (!token) return;

      const response = await fetch('/api/ignored-files/stats', {
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });

      if (response.ok) {
        const data = await response.json();
        setStats(data);
      }
    } catch (err) {
      console.error('Error fetching stats:', err);
    }
  };

  useEffect(() => {
    // Set initial filters from URL params
    if (sourceTypeParam) {
      setSourceTypeFilter(sourceTypeParam);
    }
    fetchSources();
  }, []);

  useEffect(() => {
    fetchIgnoredFiles();
    fetchStats();
  }, [page, searchTerm, sourceTypeFilter]);

  const fetchSources = async () => {
    try {
      const token = localStorage.getItem('token');
      if (!token) return;

      const response = await fetch('/api/sources', {
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });

      if (response.ok) {
        const data = await response.json();
        setSources(data);
      }
    } catch (err) {
      console.error('Error fetching sources:', err);
    }
  };

  const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(event.target.value);
    setPage(1);
  };

  const handleSourceTypeFilter = (event: any) => {
    setSourceTypeFilter(event.target.value);
    setPage(1);
  };

  const handleSelectFile = (fileId: string) => {
    const newSelected = new Set(selectedFiles);
    if (newSelected.has(fileId)) {
      newSelected.delete(fileId);
    } else {
      newSelected.add(fileId);
    }
    setSelectedFiles(newSelected);
  };

  const handleSelectAll = () => {
    if (selectedFiles.size === ignoredFiles.length) {
      setSelectedFiles(new Set());
    } else {
      setSelectedFiles(new Set(ignoredFiles.map(file => file.id)));
    }
  };

  const handleDeleteSelected = async () => {
    if (selectedFiles.size === 0) return;

    setDeletingFiles(true);
    try {
      const token = localStorage.getItem('token');
      if (!token) {
        throw new Error('No authentication token found');
      }

      const response = await fetch('/api/ignored-files/bulk-delete', {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          ignored_file_ids: Array.from(selectedFiles)
        }),
      });

      if (!response.ok) {
        throw new Error(`Failed to delete ignored files: ${response.statusText}`);
      }

      const data = await response.json();
      addNotification({
        type: 'success',
        title: 'Files Deleted',
        message: data.message
      });
      setSelectedFiles(new Set());
      setBulkDeleteDialog(false);
      fetchIgnoredFiles();
      fetchStats();
    } catch (err) {
      addNotification({
        type: 'error',
        title: 'Delete Failed',
        message: err instanceof Error ? err.message : 'Failed to delete ignored files'
      });
    } finally {
      setDeletingFiles(false);
    }
  };

  const handleDeleteSingle = async (fileId: string) => {
    try {
      const token = localStorage.getItem('token');
      if (!token) {
        throw new Error('No authentication token found');
      }

      const response = await fetch(`/api/ignored-files/${fileId}`, {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        throw new Error(`Failed to delete ignored file: ${response.statusText}`);
      }

      const data = await response.json();
      addNotification({
        type: 'success',
        title: 'Files Deleted',
        message: data.message
      });
      fetchIgnoredFiles();
      fetchStats();
    } catch (err) {
      addNotification({
        type: 'error',
        title: 'Delete Failed',
        message: err instanceof Error ? err.message : 'Failed to delete ignored file'
      });
    }
  };

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

  const getSourceIcon = (sourceType?: string) => {
    switch (sourceType) {
      case 'webdav':
        return <CloudIcon fontSize="small" />;
      case 'local_folder':
        return <ComputerIcon fontSize="small" />;
      case 's3':
        return <StorageIcon fontSize="small" />;
      default:
        return <FolderIcon fontSize="small" />;
    }
  };

  const getSourceTypeDisplay = (sourceType?: string) => {
    switch (sourceType) {
      case 'webdav':
        return 'WebDAV';
      case 'local_folder':
        return 'Local Folder';
      case 's3':
        return 'S3';
      default:
        return sourceType || 'Unknown';
    }
  };

  const getSourceNameFromIdentifier = (sourceIdentifier?: string, sourceType?: string) => {
    // Try to find the source name from the sources list
    const source = sources.find(s => s.id === sourceIdentifier || s.name.toLowerCase().includes(sourceIdentifier?.toLowerCase() || ''));
    return source?.name || sourceIdentifier || 'Unknown Source';
  };

  const clearFilters = () => {
    setSourceTypeFilter('');
    setSearchTerm('');
    setPage(1);
    navigate('/ignored-files', { replace: true });
  };

  const uniqueSourceTypes = Array.from(
    new Set(ignoredFiles.map(file => file.source_type).filter(Boolean))
  );

  return (
    <Box sx={{ p: 3 }}>
      {/* Breadcrumbs and Navigation */}
      <Box sx={{ mb: 3 }}>
        <Breadcrumbs aria-label="breadcrumb" sx={{ mb: 2 }}>
          <Link
            color="inherit"
            href="#"
            onClick={() => navigate('/sources')}
            sx={{ display: 'flex', alignItems: 'center', textDecoration: 'none' }}
          >
            <StorageIcon sx={{ mr: 0.5 }} fontSize="inherit" />
            Sources
          </Link>
          <Typography color="text.primary" sx={{ display: 'flex', alignItems: 'center' }}>
            <BlockIcon sx={{ mr: 0.5 }} fontSize="inherit" />
            Ignored Files
            {(sourceTypeParam || sourceNameParam) && (
              <Chip
                label={sourceNameParam ? `${sourceNameParam}` : `${getSourceTypeDisplay(sourceTypeParam)} Sources`}
                size="small"
                onDelete={clearFilters}
                sx={{ ml: 1 }}
              />
            )}
          </Typography>
        </Breadcrumbs>
      </Box>

      <Typography variant="h4" gutterBottom sx={{ fontWeight: 'bold' }}>
        <BlockIcon sx={{ mr: 1, verticalAlign: 'middle' }} />
        Ignored Files
        {(sourceTypeParam || sourceNameParam || sourceIdParam) && (
          <Button
            variant="outlined"
            size="small"
            startIcon={<ArrowBackIcon />}
            onClick={clearFilters}
            sx={{ ml: 2, textTransform: 'none' }}
          >
            View All
          </Button>
        )}
      </Typography>

      <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
        {sourceTypeParam || sourceNameParam || sourceIdParam
          ? `Files from ${sourceNameParam || getSourceTypeDisplay(sourceTypeParam)} sources that have been deleted and will be ignored during future syncs.`
          : 'Files that have been deleted and will be ignored during future syncs from their sources.'
        }
      </Typography>

      {/* Statistics Cards */}
      {stats && (
        <Box sx={{ mb: 3 }}>
          <Stack direction={{ xs: 'column', md: 'row' }} spacing={2}>
            <Card variant="outlined">
              <CardContent>
                <Typography variant="h6" color="primary">
                  {stats.total_ignored_files}
                </Typography>
                <Typography variant="body2" color="text.secondary">
                  Total Ignored Files
                </Typography>
              </CardContent>
            </Card>
            <Card variant="outlined">
              <CardContent>
                <Typography variant="h6" color="primary">
                  {formatFileSize(stats.total_size_bytes)}
                </Typography>
                <Typography variant="body2" color="text.secondary">
                  Total Size
                </Typography>
              </CardContent>
            </Card>
            {stats.most_recent_ignored_at && (
              <Card variant="outlined">
                <CardContent>
                  <Typography variant="h6" color="primary">
                    {formatDistanceToNow(new Date(stats.most_recent_ignored_at), { addSuffix: true })}
                  </Typography>
                  <Typography variant="body2" color="text.secondary">
                    Most Recent
                  </Typography>
                </CardContent>
              </Card>
            )}
          </Stack>
        </Box>
      )}

      {/* Filters and Search */}
      <Card variant="outlined" sx={{ mb: 3 }}>
        <CardContent>
          <Stack direction={{ xs: 'column', md: 'row' }} spacing={2} alignItems="center">
            <TextField
              placeholder="Search filenames..."
              variant="outlined"
              size="small"
              value={searchTerm}
              onChange={handleSearch}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <SearchIcon />
                  </InputAdornment>
                ),
              }}
              sx={{ flexGrow: 1 }}
            />
            
            <FormControl size="small" sx={{ minWidth: 150 }}>
              <InputLabel>Source Type</InputLabel>
              <Select
                value={sourceTypeFilter}
                label="Source Type"
                onChange={handleSourceTypeFilter}
              >
                <MenuItem value="">All Sources</MenuItem>
                {uniqueSourceTypes.map(sourceType => (
                  <MenuItem key={sourceType} value={sourceType}>
                    {getSourceTypeDisplay(sourceType)}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>

            <Button
              variant="outlined"
              startIcon={<RefreshIcon />}
              onClick={() => {
                fetchIgnoredFiles();
                fetchStats();
              }}
            >
              Refresh
            </Button>
          </Stack>
        </CardContent>
      </Card>

      {/* Bulk Actions */}
      {selectedFiles.size > 0 && (
        <Card variant="outlined" sx={{ mb: 2, bgcolor: 'action.selected' }}>
          <CardContent>
            <Stack direction="row" spacing={2} alignItems="center">
              <Typography variant="body2">
                {selectedFiles.size} file{selectedFiles.size !== 1 ? 's' : ''} selected
              </Typography>
              <Button
                variant="contained"
                color="success"
                startIcon={<RestoreFromTrashIcon />}
                onClick={() => setBulkDeleteDialog(true)}
                size="small"
              >
                Remove from Ignored List
              </Button>
            </Stack>
          </CardContent>
        </Card>
      )}

      {/* Files Table */}
      <Card variant="outlined">
        <TableContainer>
          <Table>
            <TableHead>
              <TableRow>
                <TableCell padding="checkbox">
                  <Checkbox
                    indeterminate={selectedFiles.size > 0 && selectedFiles.size < ignoredFiles.length}
                    checked={ignoredFiles.length > 0 && selectedFiles.size === ignoredFiles.length}
                    onChange={handleSelectAll}
                  />
                </TableCell>
                <TableCell>Filename</TableCell>
                <TableCell>Source</TableCell>
                <TableCell>Size</TableCell>
                <TableCell>Ignored Date</TableCell>
                <TableCell>Reason</TableCell>
                <TableCell>Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {loading ? (
                <TableRow>
                  <TableCell colSpan={7} align="center">
                    <CircularProgress />
                  </TableCell>
                </TableRow>
              ) : error ? (
                <TableRow>
                  <TableCell colSpan={7}>
                    <Alert severity="error">{error}</Alert>
                  </TableCell>
                </TableRow>
              ) : ignoredFiles.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={7} align="center">
                    <Typography variant="body2" color="text.secondary">
                      No ignored files found
                    </Typography>
                  </TableCell>
                </TableRow>
              ) : (
                ignoredFiles.map((file) => (
                  <TableRow key={file.id} hover>
                    <TableCell padding="checkbox">
                      <Checkbox
                        checked={selectedFiles.has(file.id)}
                        onChange={() => handleSelectFile(file.id)}
                      />
                    </TableCell>
                    <TableCell>
                      <Box>
                        <Typography variant="body2" fontWeight="medium">
                          {file.filename}
                        </Typography>
                        {file.filename !== file.original_filename && (
                          <Typography variant="caption" color="text.secondary">
                            Original: {file.original_filename}
                          </Typography>
                        )}
                        <Typography variant="caption" color="text.secondary" display="block">
                          {file.mime_type}
                        </Typography>
                      </Box>
                    </TableCell>
                    <TableCell>
                      <Stack direction="row" spacing={1} alignItems="center">
                        {getSourceIcon(file.source_type)}
                        <Box>
                          <Typography variant="body2">
                            {getSourceTypeDisplay(file.source_type)}
                          </Typography>
                          {file.source_path && (
                            <Typography variant="caption" color="text.secondary">
                              {file.source_path}
                            </Typography>
                          )}
                        </Box>
                      </Stack>
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2">
                        {formatFileSize(file.file_size)}
                      </Typography>
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2">
                        {format(new Date(file.ignored_at), 'MMM dd, yyyy')}
                      </Typography>
                      <Typography variant="caption" color="text.secondary">
                        {formatDistanceToNow(new Date(file.ignored_at), { addSuffix: true })}
                      </Typography>
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2">
                        {file.reason || 'No reason provided'}
                      </Typography>
                    </TableCell>
                    <TableCell>
                      <Stack direction="row" spacing={1}>
                        <Tooltip title="Remove from ignored list (allow re-syncing)">
                          <IconButton
                            size="small"
                            onClick={() => handleDeleteSingle(file.id)}
                            color="success"
                          >
                            <RestoreFromTrashIcon fontSize="small" />
                          </IconButton>
                        </Tooltip>
                      </Stack>
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </TableContainer>

        {/* Pagination */}
        {totalPages > 1 && (
          <Box sx={{ p: 2, display: 'flex', justifyContent: 'center' }}>
            <Pagination
              count={totalPages}
              page={page}
              onChange={(_, newPage) => setPage(newPage)}
              color="primary"
            />
          </Box>
        )}
      </Card>

      {/* Bulk Delete Confirmation Dialog */}
      <Dialog open={bulkDeleteDialog} onClose={() => setBulkDeleteDialog(false)}>
        <DialogTitle>Confirm Bulk Delete</DialogTitle>
        <DialogContent>
          <Typography>
            Are you sure you want to remove {selectedFiles.size} file{selectedFiles.size !== 1 ? 's' : ''} from the ignored list?
          </Typography>
          <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
            These files will be eligible for syncing again if encountered from their sources. This action allows them to be re-imported during future syncs.
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setBulkDeleteDialog(false)}>Cancel</Button>
          <Button
            onClick={handleDeleteSelected}
            color="success"
            variant="contained"
            disabled={deletingFiles}
            startIcon={deletingFiles ? <CircularProgress size={16} /> : <RestoreFromTrashIcon />}
          >
            Remove from Ignored List
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default IgnoredFilesPage;