import * as React from 'react';
import {
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Checkbox,
  TablePagination,
  TextField,
  InputAdornment,
  Box,
  Typography,
  Chip,
  CircularProgress,
  Alert,
  IconButton,
  Tooltip,
} from '@mui/material';
import {
  Search as SearchIcon,
  Visibility as VisibilityIcon,
  Edit as EditIcon,
  Delete as DeleteIcon,
} from '@mui/icons-material';

import * as Types from 'types/types';
import { useAuth } from 'hooks/AuthContext';

interface JobsTableProps {
  onJobSelect?: (selectedJobs: Types.Job[]) => void;
  onJobView?: (job: Types.Job) => void;
  onJobEdit?: (job: Types.Job) => void;
  onJobDelete?: (job: Types.Job) => void;
  selectable?: boolean;
  showActions?: boolean;
}

const JobsTable: React.FC<JobsTableProps> = ({
  onJobSelect,
  onJobView,
  onJobEdit,
  onJobDelete,
  selectable = true,
  showActions = true,
}) => {
  const { apiClient } = useAuth();
  const [jobs, setJobs] = React.useState<Types.Job[]>([]);
  const [loading, setLoading] = React.useState<boolean>(true);
  const [error, setError] = React.useState<string | null>(null);
  const [page, setPage] = React.useState<number>(0);
  const [limit, setLimit] = React.useState<number>(25);
  const [total, setTotal] = React.useState<number>(0);
  const [searchQuery, setSearchQuery] = React.useState<string>('');
  const [searchTimeout, setSearchTimeout] = React.useState<NodeJS.Timeout | null>(null);
  const [selectedJobs, setSelectedJobs] = React.useState<Set<string>>(new Set());

  // Fetch jobs from API
  const fetchJobs = React.useCallback(
    async (pageNum = 0, searchTerm = '') => {
      try {
        setLoading(true);
        setError(null);
        const paginationRequest: Partial<Types.PaginatedRequest> = {
          page: pageNum + 1,
          limit: limit,
          sortBy: 'createdAt',
          sortOrder: 'desc',
        };

        let paginationResponse: Types.PaginatedResponse;
        if (searchTerm.trim()) {
          paginationResponse = await apiClient.searchJobs(searchTerm);
        } else {
          paginationResponse = await apiClient.getJobs(paginationRequest);
        }

        setJobs(paginationResponse.data);
        setTotal(paginationResponse.totalPages);
      } catch (err) {
        setError(err instanceof Error ? err.message : 'An error occurred while fetching jobs');
        setJobs([]);
        setTotal(0);
      } finally {
        setLoading(false);
      }
    },
    [limit, apiClient]
  );

  // Initial load
  React.useEffect(() => {
    fetchJobs(0, searchQuery);
  }, [fetchJobs, searchQuery]);

  // Handle search with debouncing
  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    const value = event.target.value;
    setSearchQuery(value);

    if (searchTimeout) {
      clearTimeout(searchTimeout);
    }

    const timeout = setTimeout(() => {
      setPage(0);
      fetchJobs(0, value);
    }, 500);

    setSearchTimeout(timeout);
  };

  // Handle page change
  const handlePageChange = (event: unknown, newPage: number): void => {
    setPage(newPage);
    fetchJobs(newPage, searchQuery);
  };

  // Handle rows per page change
  const handleRowsPerPageChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    const newLimit = parseInt(event.target.value, 10);
    setLimit(newLimit);
    setPage(0);
    fetchJobs(0, searchQuery);
  };

  // Handle selection
  const handleSelectAll = (event: React.ChangeEvent<HTMLInputElement>): void => {
    if (event.target.checked) {
      const newSelected = new Set<string>(jobs.map(job => job.id || ''));
      setSelectedJobs(newSelected);
      onJobSelect?.(jobs);
    } else {
      setSelectedJobs(new Set());
      onJobSelect?.([]);
    }
  };

  const handleSelectJob = (jobId: string): void => {
    const newSelected = new Set(selectedJobs);
    if (newSelected.has(jobId)) {
      newSelected.delete(jobId);
    } else {
      newSelected.add(jobId);
    }
    setSelectedJobs(newSelected);

    const selectedJobsList = jobs.filter(job => newSelected.has(job.id || ''));
    onJobSelect?.(selectedJobsList);
  };

  const getOwnerName = (owner?: Types.Job['owner']): string => {
    if (!owner) return 'Unknown';
    return `${owner.firstName || ''} ${owner.lastName || ''}`.trim() || owner.email || 'Unknown';
  };

  const truncateDescription = (description: string, maxLength = 100): string => {
    if (description.length <= maxLength) return description;
    return description.substring(0, maxLength) + '...';
  };

  const isSelected = (jobId: string): boolean => selectedJobs.has(jobId);
  const numSelected = selectedJobs.size;
  const rowCount = jobs.length;

  if (error) {
    return (
      <Paper sx={{ p: 2 }}>
        <Alert severity="error">{error}</Alert>
      </Paper>
    );
  }

  return (
    <Paper>
      <Box sx={{ p: 2 }}>
        <Typography variant="h6" component="h2" sx={{ mb: 2 }}>
          Jobs ({total})
        </Typography>

        <TextField
          fullWidth
          size="small"
          placeholder="Search jobs by title, description, or skills..."
          value={searchQuery}
          onChange={handleSearchChange}
          InputProps={{
            startAdornment: (
              <InputAdornment position="start">
                <SearchIcon />
              </InputAdornment>
            ),
          }}
          sx={{ mb: 2 }}
        />
      </Box>

      <TableContainer>
        <Table size="small" aria-label="jobs table">
          <TableHead sx={{ '& th': { whiteSpace: 'nowrap' } }}>
            <TableRow>
              {selectable && (
                <TableCell padding="checkbox">
                  <Checkbox
                    color="primary"
                    indeterminate={numSelected > 0 && numSelected < rowCount}
                    checked={rowCount > 0 && numSelected === rowCount}
                    onChange={handleSelectAll}
                    inputProps={{
                      'aria-label': 'select all jobs',
                    }}
                  />
                </TableCell>
              )}
              <TableCell>Title</TableCell>
              <TableCell>Description</TableCell>
              {/* <TableCell>Skills</TableCell> */}
              <TableCell>Owner</TableCell>
              {/* <TableCell align="right">Views</TableCell> */}
              <TableCell>Status</TableCell>
              <TableCell>Created</TableCell>
              {showActions && <TableCell align="center">Actions</TableCell>}
            </TableRow>
          </TableHead>
          <TableBody sx={{ '& p, & td': { m: 0, p: 0.5, fontSize: '0.75rem !important' } }}>
            {loading ? (
              <TableRow>
                <TableCell
                  colSpan={selectable ? (showActions ? 9 : 8) : showActions ? 8 : 7}
                  align="center"
                >
                  <CircularProgress size={24} />
                </TableCell>
              </TableRow>
            ) : jobs.length === 0 ? (
              <TableRow>
                <TableCell
                  colSpan={selectable ? (showActions ? 9 : 8) : showActions ? 8 : 7}
                  align="center"
                >
                  <Typography variant="body2" color="textSecondary">
                    No jobs found
                  </Typography>
                </TableCell>
              </TableRow>
            ) : (
              jobs.map(job => {
                const isItemSelected = isSelected(job.id || '');
                return (
                  <TableRow
                    key={job.id}
                    hover
                    role="checkbox"
                    aria-checked={isItemSelected}
                    selected={isItemSelected}
                    sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
                  >
                    {selectable && (
                      <TableCell padding="checkbox">
                        <Checkbox
                          color="primary"
                          checked={isItemSelected}
                          onChange={(): void => handleSelectJob(job.id || '')}
                          inputProps={{
                            'aria-labelledby': `job-${job.id}`,
                          }}
                        />
                      </TableCell>
                    )}
                    <TableCell scope="row" id={`job-${job.id}`}>
                      <Typography variant="body2" fontWeight="medium">
                        {job.title}
                      </Typography>
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2" color="textSecondary">
                        {truncateDescription(job.description)}
                      </Typography>
                    </TableCell>
                    {/* <TableCell>
                      <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                        {job.skills?.slice(0, 3).map((skill) => (
                          <Chip key={skill} label={skill} size="small" variant="outlined" />
                        ))}
                        {job.skills && job.skills.length > 3 && (
                          <Chip label={`+${job.skills.length - 3}`} size="small" />
                        )}
                      </Box>
                    </TableCell> */}
                    <TableCell>
                      <Typography variant="body2">{getOwnerName(job.owner)}</Typography>
                    </TableCell>
                    {/* <TableCell align="right">
                      <Typography variant="body2">
                        {job.views}
                      </Typography>
                    </TableCell> */}
                    <TableCell>
                      <Chip
                        label={job.details?.isActive ? 'Active' : 'Inactive'}
                        color={job.details?.isActive ? 'success' : 'default'}
                        size="small"
                      />
                    </TableCell>
                    <TableCell sx={{ whiteSpace: 'nowrap' }}>
                      <Typography variant="body2">{job.createdAt?.toLocaleDateString()}</Typography>
                    </TableCell>
                    {showActions && (
                      <TableCell align="center">
                        <Box sx={{ display: 'flex', gap: 0.5 }}>
                          {onJobView && (
                            <Tooltip title="View Job">
                              <IconButton size="small" onClick={(): void => onJobView(job)}>
                                <VisibilityIcon fontSize="small" />
                              </IconButton>
                            </Tooltip>
                          )}
                          {onJobEdit && (
                            <Tooltip title="Edit Job">
                              <IconButton size="small" onClick={(): void => onJobEdit(job)}>
                                <EditIcon fontSize="small" />
                              </IconButton>
                            </Tooltip>
                          )}
                          {onJobDelete && (
                            <Tooltip title="Delete Job">
                              <IconButton size="small" onClick={(): void => onJobDelete(job)}>
                                <DeleteIcon fontSize="small" />
                              </IconButton>
                            </Tooltip>
                          )}
                        </Box>
                      </TableCell>
                    )}
                  </TableRow>
                );
              })
            )}
          </TableBody>
        </Table>
      </TableContainer>

      <TablePagination
        rowsPerPageOptions={[10, 25, 50, 100]}
        component="div"
        count={total}
        rowsPerPage={limit}
        page={page}
        onPageChange={handlePageChange}
        onRowsPerPageChange={handleRowsPerPageChange}
      />
    </Paper>
  );
};

export { JobsTable };
