import React, { useEffect } from 'react';
import {
  Box,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Typography,
  FormControl,
  Select,
  MenuItem,
  InputLabel,
  Chip,
  IconButton,
  Dialog,
  AppBar,
  Toolbar,
  useMediaQuery,
  useTheme,
  Slide,
  Checkbox,
  TablePagination,
  TextField,
  InputAdornment,
  CircularProgress,
  Alert,
  Tooltip,
  Grid,
  SxProps,
} from '@mui/material';
import {
  KeyboardArrowUp as ArrowUpIcon,
  KeyboardArrowDown as ArrowDownIcon,
  Business as BusinessIcon,
  Work as WorkIcon,
  Schedule as ScheduleIcon,
  ArrowBack as ArrowBackIcon,
  Search as SearchIcon,
  Visibility as VisibilityIcon,
  Edit as EditIcon,
  Delete as DeleteIcon,
  Close as CloseIcon,
} from '@mui/icons-material';
import { TransitionProps } from '@mui/material/transitions';
import * as Types from 'types/types'; // Adjust the import path as necessary
import { useAuth } from 'hooks/AuthContext';
import { StyledMarkdown } from 'components/StyledMarkdown';
import { Scrollable } from 'components/Scrollable';
import { useLocation } from 'react-router-dom';

// async searchJobs(query: string): Promise<Types.PaginatedResponse> {
//   const results = await this.getJobs();
//   const filtered = results.data.filter(job =>
//     job.title.toLowerCase().includes(query.toLowerCase()) ||
//     job.description.toLowerCase().includes(query.toLowerCase()) ||
//     job.company?.toLowerCase().includes(query.toLowerCase())
//   );
//   return {
//     data: filtered,
//     totalPages: 1,
//     totalItems: filtered.length,
//   };
// }

type SortField = 'updatedAt' | 'createdAt' | 'company' | 'title';
type SortOrder = 'asc' | 'desc';

interface JobsViewProps {
  filter?: Record<string, string | number | boolean>;
  onJobSelect?: (selectedJobs: Types.Job[]) => void;
  onJobView?: (job: Types.Job) => void;
  onJobEdit?: (job: Types.Job) => void;
  onJobDelete?: (job: Types.Job) => Promise<void>;
  selectable?: boolean;
  showActions?: boolean;
  showDetailsPanel?: boolean;
  variant?: 'table' | 'list' | 'responsive';
  sx?: SxProps;
}

const Transition = React.forwardRef(function Transition(
  props: TransitionProps & {
    children: React.ReactElement;
  },
  ref: React.Ref<unknown>
) {
  return <Slide direction="up" ref={ref} {...props} />;
});

const JobInfoPanel: React.FC<{ job: Types.Job; onClose?: () => void; inDialog?: boolean }> = ({
  job,
  onClose,
  inDialog = false,
}) => (
  <Box
    sx={{
      p: inDialog ? 2 : 1.5,
      height: '100%',
    }}
  >
    <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', mb: 2 }}>
      <Typography variant="h5" component="h1" gutterBottom>
        {job.title}
      </Typography>
      {onClose && !inDialog && (
        <IconButton onClick={onClose} size="small">
          <CloseIcon />
        </IconButton>
      )}
    </Box>

    <Typography variant="h6" color="primary" gutterBottom>
      {job.company}
    </Typography>

    <Box sx={{ mb: 2 }}>
      <Chip
        label={job.details?.isActive ? 'Active' : 'Inactive'}
        color={job.details?.isActive ? 'success' : 'default'}
        size="small"
        sx={{ mr: 1 }}
      />
      {job.details?.employmentType && (
        <Chip label={job.details.employmentType} variant="outlined" size="small" sx={{ mr: 1 }} />
      )}
    </Box>

    {job.details?.location && (
      <Typography variant="body2" color="text.secondary" gutterBottom>
        📍 {job.details.location.city}, {job.details.location.state || job.details.location.country}
      </Typography>
    )}

    <StyledMarkdown content={job.description} />

    {job.requirements &&
      job.requirements.technicalSkills &&
      job.requirements.technicalSkills.required &&
      job.requirements.technicalSkills.required.length > 0 && (
        <Box sx={{ mt: 2 }}>
          <Typography variant="subtitle2" gutterBottom>
            Required Skills
          </Typography>
          <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
            {job.requirements.technicalSkills.required.map(skill => (
              <Chip key={skill} label={skill} size="small" variant="outlined" />
            ))}
          </Box>
        </Box>
      )}

    <Box sx={{ mt: 3, pt: 2, borderTop: 1, borderColor: 'divider' }}>
      <Typography variant="body2" color="text.secondary">
        Posted: {job.createdAt?.toLocaleDateString()}
      </Typography>
      <Typography variant="body2" color="text.secondary">
        Updated: {job.updatedAt?.toLocaleDateString()}
      </Typography>
      {/* {job.views && (
        <Typography variant="body2" color="text.secondary">
          Views: {job.views}
        </Typography>
      )} */}
    </Box>
  </Box>
);

const JobsView: React.FC<JobsViewProps> = ({
  onJobSelect,
  onJobView,
  onJobEdit,
  onJobDelete,
  selectable = true,
  showActions = true,
  showDetailsPanel = true,
  filter = {},
  sx = {},
}) => {
  const theme = useTheme();
  const { apiClient, user } = useAuth();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
  const isSmall = useMediaQuery(theme.breakpoints.down('sm'));
  const location = useLocation();

  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());
  const [selectedJob, setSelectedJob] = React.useState<Types.Job | null>(null);
  const [sortField, setSortField] = React.useState<SortField>('updatedAt');
  const [sortOrder, setSortOrder] = React.useState<SortOrder>('desc');
  const [mobileDialogOpen, setMobileDialogOpen] = React.useState(false);
  const [detailsPanelOpen, setDetailsPanelOpen] = React.useState(showDetailsPanel);

  if (location.pathname.indexOf('/candidate/jobs') === 0) {
    filter = { ...filter, owner_id: user?.id || '' };
  }

  const fetchJobs = React.useCallback(
    async (pageNum = 0, searchTerm = '') => {
      try {
        setLoading(true);
        setError(null);
        const paginationRequest: Partial<Types.PaginatedRequest> = {
          page: pageNum + 1,
          limit: limit,
          sortBy: sortField,
          sortOrder: sortOrder,
          filters: filter,
        };

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

        const sortedJobs = sortJobs(paginationResponse.data, sortField, sortOrder);
        let updated = false;
        if (jobs.length) {
          if (sortedJobs.length !== jobs.length) {
            updated = true;
          } else {
            for (let i = 0; i < sortedJobs.length; i++) {
              if (sortedJobs[i].id !== jobs[i].id) {
                updated = true;
                break;
              }
            }
          }
        } else {
          updated = true;
        }
        if (updated) {
          setJobs(sortedJobs);
          setTotal(paginationResponse.total);
        }
      } catch (err) {
        setError(err instanceof Error ? err.message : 'An error occurred while fetching jobs');
        setJobs([]);
        setTotal(0);
      } finally {
        setLoading(false);
      }
    },
    [limit, sortField, sortOrder, apiClient]
  );

  useEffect(() => {
    if (jobs.length > 0 && !selectedJob && detailsPanelOpen) {
      console.log('Setting selected job from fetchJobs');
      setSelectedJob(jobs[0]);
    }
  }, [jobs, selectedJob, detailsPanelOpen]);

  React.useEffect(() => {
    console.log('Fetching jobs with filter:', filter, 'searchQuery:', searchQuery);
    fetchJobs(0, searchQuery);
  }, [fetchJobs, searchQuery]);

  const sortJobs = (jobsList: Types.Job[], field: SortField, order: SortOrder): Types.Job[] => {
    return [...jobsList].sort((a, b) => {
      let aValue: number | string;
      let bValue: number | string;

      switch (field) {
        case 'updatedAt':
          aValue = a.updatedAt?.getTime() || 0;
          bValue = b.updatedAt?.getTime() || 0;
          break;
        case 'createdAt':
          aValue = a.createdAt?.getTime() || 0;
          bValue = b.createdAt?.getTime() || 0;
          break;
        case 'company':
          aValue = a.company?.toLowerCase() || '';
          bValue = b.company?.toLowerCase() || '';
          break;
        case 'title':
          aValue = a.title?.toLowerCase() || '';
          bValue = b.title?.toLowerCase() || '';
          break;
        default:
          return 0;
      }

      if (aValue < bValue) return order === 'asc' ? -1 : 1;
      if (aValue > bValue) return order === 'asc' ? 1 : -1;
      return 0;
    });
  };

  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
    console.log('Handling search change:', event.target.value);
    const value = event.target.value;
    setSearchQuery(value);

    if (searchTimeout) {
      clearTimeout(searchTimeout);
    }

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

    setSearchTimeout(timeout);
  };

  const handlePageChange = (event: unknown, newPage: number): void => {
    console.log('Handling page change:', newPage);
    setPage(newPage);
    fetchJobs(newPage, searchQuery);
  };

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

  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 handleSort = (field: SortField): void => {
    if (sortField === field) {
      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
    } else {
      setSortField(field);
      setSortOrder('desc');
    }
  };

  const handleJobRowClick = (job: Types.Job): void => {
    setSelectedJob(job);
    if (isMobile) {
      setMobileDialogOpen(true);
    } else if (detailsPanelOpen || !isMobile) {
      setDetailsPanelOpen(true);
    }
    onJobView?.(job);
  };

  const getOwnerName = (owner?: Types.BaseUser): 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 formatDate = (date: Date | undefined): string => {
    if (!date) return 'N/A';
    return new Intl.DateTimeFormat('en-US', {
      month: 'short',
      day: 'numeric',
      ...(isMobile ? {} : { year: 'numeric' }),
      ...(isSmall ? {} : { hour: '2-digit', minute: '2-digit' }),
    }).format(date);
  };

  const getSortIcon = (field: SortField): React.ReactElement => {
    if (sortField !== field) return <></>;
    return sortOrder === 'asc' ? (
      <ArrowUpIcon fontSize="small" />
    ) : (
      <ArrowDownIcon fontSize="small" />
    );
  };

  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>
    );
  }

  const tableContent = (
    <>
      <Box sx={{ p: 2 }}>
        <Grid container spacing={2} alignItems="center">
          <Grid size={{ xs: 12, md: 6 }}>
            <Typography variant="h6" component="h2">
              Jobs ({total})
            </Typography>
          </Grid>
          <Grid size={{ xs: 12, md: 6 }}>
            <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
              <TextField
                fullWidth
                size="small"
                placeholder="Search jobs..."
                value={searchQuery}
                onChange={handleSearchChange}
                InputProps={{
                  startAdornment: (
                    <InputAdornment position="start">
                      <SearchIcon />
                    </InputAdornment>
                  ),
                }}
              />
              <FormControl size="small" sx={{ minWidth: 150 }}>
                <InputLabel>Sort</InputLabel>
                <Select
                  value={`${sortField}-${sortOrder}`}
                  label="Sort"
                  onChange={(e): void => {
                    const [field, order] = e.target.value.split('-') as [SortField, SortOrder];
                    setSortField(field);
                    setSortOrder(order);
                  }}
                >
                  <MenuItem value="updatedAt-desc">Updated ↓</MenuItem>
                  <MenuItem value="updatedAt-asc">Updated ↑</MenuItem>
                  <MenuItem value="createdAt-desc">Created ↓</MenuItem>
                  <MenuItem value="createdAt-asc">Created ↑</MenuItem>
                  <MenuItem value="company-asc">Company A-Z</MenuItem>
                  <MenuItem value="company-desc">Company Z-A</MenuItem>
                  <MenuItem value="title-asc">Title A-Z</MenuItem>
                  <MenuItem value="title-desc">Title Z-A</MenuItem>
                </Select>
              </FormControl>
            </Box>
          </Grid>
        </Grid>
      </Box>

      <TableContainer>
        <Table size="small" aria-label="jobs table">
          <TableHead>
            <TableRow sx={{ '& th': { whiteSpace: 'nowrap' } }}>
              {selectable && (
                <TableCell padding="checkbox">
                  <Checkbox
                    color="primary"
                    indeterminate={numSelected > 0 && numSelected < rowCount}
                    checked={rowCount > 0 && numSelected === rowCount}
                    onChange={handleSelectAll}
                  />
                </TableCell>
              )}
              <TableCell sx={{ cursor: 'pointer' }} onClick={(): void => handleSort('company')}>
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                  <BusinessIcon fontSize="small" />
                  Company {getSortIcon('company')}
                </Box>
              </TableCell>
              <TableCell sx={{ cursor: 'pointer' }} onClick={(): void => handleSort('title')}>
                <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                  <WorkIcon fontSize="small" />
                  Title {getSortIcon('title')}
                </Box>
              </TableCell>
              <TableCell>Description</TableCell>
              {!isMobile && (
                <>
                  <TableCell>Owner</TableCell>
                  <TableCell
                    sx={{ cursor: 'pointer' }}
                    onClick={(): void => handleSort('updatedAt')}
                  >
                    <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
                      <ScheduleIcon fontSize="small" />
                      Updated {getSortIcon('updatedAt')}
                    </Box>
                  </TableCell>
                </>
              )}
              {/* <TableCell>Status</TableCell> */}
              {!isMobile && showActions && <TableCell align="center">Actions</TableCell>}
            </TableRow>
          </TableHead>
          <TableBody>
            {loading ? (
              <TableRow>
                <TableCell colSpan={8} align="center">
                  <CircularProgress size={24} />
                </TableCell>
              </TableRow>
            ) : jobs.length === 0 ? (
              <TableRow>
                <TableCell colSpan={8} 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
                    selected={isItemSelected || selectedJob?.id === job.id}
                    onClick={(): void => handleJobRowClick(job)}
                    sx={{ cursor: 'pointer' }}
                  >
                    {selectable && (
                      <TableCell padding="checkbox" onClick={(e): void => e.stopPropagation()}>
                        <Checkbox
                          color="primary"
                          checked={isItemSelected}
                          onChange={(): void => handleSelectJob(job.id || '')}
                        />
                      </TableCell>
                    )}
                    <TableCell>
                      <Typography variant="body2" fontWeight="medium">
                        {job.company}
                      </Typography>
                      {job.details?.location && (
                        <Typography variant="caption" color="text.secondary">
                          {job.details.location.city}, {job.details.location.state}
                        </Typography>
                      )}
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2" fontWeight="medium">
                        {job.title}
                      </Typography>
                      {job.details?.employmentType && (
                        <Chip
                          label={job.details.employmentType}
                          size="small"
                          variant="outlined"
                          sx={{ mt: 0.5 }}
                        />
                      )}
                    </TableCell>
                    <TableCell>
                      <Typography variant="body2" color="textSecondary">
                        {truncateDescription(job.summary || job.description || '', 100)}
                      </Typography>
                    </TableCell>
                    {!isMobile && (
                      <>
                        <TableCell>
                          <Typography variant="body2">{getOwnerName(job.owner)}</Typography>
                        </TableCell>
                        <TableCell>
                          <Typography variant="body2">{formatDate(job.updatedAt)}</Typography>
                        </TableCell>
                      </>
                    )}
                    {/* <TableCell>
                      <Chip
                        label={job.details?.isActive ? 'Active' : 'Inactive'}
                        color={job.details?.isActive ? 'success' : 'default'}
                        size="small"
                      />
                    </TableCell> */}
                    {!isMobile && showActions && (
                      <TableCell align="center" onClick={(e): void => e.stopPropagation()}>
                        <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={async (): Promise<void> => {
                                  await onJobDelete(job);
                                  fetchJobs(0, searchQuery);
                                }}
                              >
                                <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}
      />
    </>
  );

  return (
    <Box sx={{ flexGrow: 1, display: 'flex', flexDirection: 'row', position: 'relative', ...sx }}>
      <Scrollable
        sx={{ display: 'flex', flex: 1, flexDirection: 'column', height: '100%', width: '100%' }}
      >
        <Paper sx={{ flex: 1, display: 'flex', flexDirection: 'column' }}>{tableContent}</Paper>
      </Scrollable>

      {detailsPanelOpen && !isMobile && (
        <Scrollable
          sx={{ display: 'flex', flex: 1, flexDirection: 'row', height: '100%', width: '100%' }}
        >
          <Paper sx={{ flex: 1, ml: 1 }}>
            {selectedJob ? (
              <JobInfoPanel
                job={selectedJob}
                onClose={(): void => {
                  console.log('Closing JobInfoPanel');
                  setDetailsPanelOpen(false);
                  setSelectedJob(null);
                }}
              />
            ) : (
              <Box
                sx={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  height: '100%',
                  color: 'text.secondary',
                  textAlign: 'center',
                  p: 2,
                }}
              >
                <Typography variant="body2">Select a job to view details</Typography>
              </Box>
            )}
          </Paper>
        </Scrollable>
      )}

      <Dialog
        fullScreen
        open={mobileDialogOpen}
        onClose={(): void => setMobileDialogOpen(false)}
        TransitionComponent={Transition}
      >
        <AppBar sx={{ position: 'relative' }}>
          <Toolbar>
            <IconButton
              edge="start"
              color="inherit"
              onClick={(): void => setMobileDialogOpen(false)}
            >
              <ArrowBackIcon />
            </IconButton>
            <Box sx={{ ml: 2, flex: 1 }}>
              <Typography variant="h6" noWrap>
                {selectedJob?.title}
              </Typography>
              <Typography variant="body2" sx={{ opacity: 0.8 }} noWrap>
                {selectedJob?.company}
              </Typography>
            </Box>
          </Toolbar>
        </AppBar>
        {selectedJob && <JobInfoPanel job={selectedJob} inDialog />}
      </Dialog>
    </Box>
  );
};

export { JobsView };
