import { useState, useEffect, useCallback, useRef } from 'react';
import {
  Container,
  Typography,
  Box,
  TextField,
  InputAdornment,
  Chip,
  Avatar,
  Tooltip,
  Alert,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  OutlinedInput,
  SelectChangeEvent,
  TablePagination,
  Paper,
} from '@mui/material';
import {
  Search as SearchIcon,
  Add as AddIcon,
  People as PeopleIcon,
} from '@mui/icons-material';
import { useNavigate } from 'react-router-dom';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import ChatAwareFab from '../components/shared/ChatAwareFab';
import { DataTable, StatusChip } from '../components/templates';
import { useAuth } from '../contexts/AuthContext';
import { usePermissionContext } from '../contexts/PermissionContext';
import { membersService } from '../services/members';
import {
  MemberListItem,
  StatusEnum,
  DienstgradEnum,
  STATUS_VALUES,
  DIENSTGRAD_VALUES,
  STATUS_LABELS,
  STATUS_COLORS,
  getMemberDisplayName,
  formatPhone,
} from '../types/member.types';

// ----------------------------------------------------------------
// Helper: determine whether the current user can write member data
// ----------------------------------------------------------------
function useCanWrite(): boolean {
  const { hasPermission } = usePermissionContext();
  return hasPermission('mitglieder:edit');
}

// ----------------------------------------------------------------
// Debounce hook
// ----------------------------------------------------------------
function useDebounce<T>(value: T, delay: number): T {
  const [debounced, setDebounced] = useState<T>(value);
  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(id);
  }, [value, delay]);
  return debounced;
}

// ----------------------------------------------------------------
// Component
// ----------------------------------------------------------------
function Mitglieder() {
  const navigate = useNavigate();
  const { user } = useAuth();
  const canWrite = useCanWrite();
  const { hasPermission } = usePermissionContext();

  // --- redirect non-privileged users to their own profile ---
  useEffect(() => {
    if (!user) return;
    if (!hasPermission('mitglieder:view_all')) {
      navigate(`/mitglieder/${(user as any).id}`, { replace: true });
    }
  }, [user, navigate, hasPermission]);

  // --- data state ---
  const [members, setMembers] = useState<MemberListItem[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // --- filter / pagination state ---
  const [searchInput, setSearchInput] = useState('');
  const debouncedSearch = useDebounce(searchInput, 300);
  const [selectedStatus, setSelectedStatus] = useState<StatusEnum[]>([]);
  const [selectedDienstgrad, setSelectedDienstgrad] = useState<DienstgradEnum[]>([]);
  const [page, setPage] = useState(0);       // MUI uses 0-based
  const [pageSize, setPageSize] = useState(25);

  // Track previous debounced search to reset page
  const prevSearch = useRef(debouncedSearch);

  // ----------------------------------------------------------------
  // Data fetching
  // ----------------------------------------------------------------
  const fetchMembers = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const { items, total: t } = await membersService.getMembers({
        search: debouncedSearch || undefined,
        status: selectedStatus.length > 0 ? selectedStatus : undefined,
        dienstgrad: selectedDienstgrad.length > 0 ? selectedDienstgrad : undefined,
        page: page + 1,  // convert to 1-based for API
        pageSize: pageSize === -1 ? 0 : pageSize,  // -1 = MUI "Alle" sentinel → 0 = backend "no limit"
      });
      setMembers(items);
      setTotal(t);
    } catch (err) {
      setError('Mitglieder konnten nicht geladen werden. Bitte versuchen Sie es erneut.');
    } finally {
      setLoading(false);
    }
  }, [debouncedSearch, selectedStatus, selectedDienstgrad, page, pageSize]);

  useEffect(() => {
    // Reset to page 0 when search changes
    if (debouncedSearch !== prevSearch.current) {
      prevSearch.current = debouncedSearch;
      setPage(0);
      return;
    }
    fetchMembers();
  }, [fetchMembers, debouncedSearch]);

  // Also fetch when page/filters change (skip initial mount to avoid double-fetch)
  const isInitialMount = useRef(true);
  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;
      return;
    }
    fetchMembers();
  }, [page, pageSize, selectedStatus, selectedDienstgrad]);

  // ----------------------------------------------------------------
  // Event handlers
  // ----------------------------------------------------------------
  const handleStatusChange = (e: SelectChangeEvent<StatusEnum[]>) => {
    setSelectedStatus(e.target.value as StatusEnum[]);
    setPage(0);
  };

  const handleDienstgradChange = (e: SelectChangeEvent<DienstgradEnum[]>) => {
    setSelectedDienstgrad(e.target.value as DienstgradEnum[]);
    setPage(0);
  };

  const handleRowClick = (userId: string) => {
    navigate(`/mitglieder/${userId}`);
  };

  const handleRemoveStatusChip = (status: StatusEnum) => {
    setSelectedStatus((prev) => prev.filter((s) => s !== status));
    setPage(0);
  };

  const handleRemoveDienstgradChip = (dg: DienstgradEnum) => {
    setSelectedDienstgrad((prev) => prev.filter((d) => d !== dg));
    setPage(0);
  };

  // ----------------------------------------------------------------
  // Render
  // ----------------------------------------------------------------
  const activeFilters = selectedStatus.length + selectedDienstgrad.length;

  return (
    <DashboardLayout>
      <Container maxWidth="xl">
        {/* Page heading */}
        <Box sx={{ display: 'flex', alignItems: 'center', mb: 3, gap: 2, flexWrap: 'wrap' }}>
          <Typography variant="h4" sx={{ flex: 1 }}>
            Mitgliederverwaltung
          </Typography>
          <Typography variant="body2" color="text.secondary">
            {loading ? '...' : `${total} Mitglieder`}
          </Typography>
        </Box>

        {/* Toolbar: search + filters */}
        <Box sx={{ display: 'flex', gap: 2, mb: 2, flexWrap: 'wrap' }}>
          <TextField
            placeholder="Suche nach Name, E-Mail oder Mitgliedsnummer…"
            size="small"
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            sx={{ flex: '1 1 280px', minWidth: 220 }}
            InputProps={{
              startAdornment: (
                <InputAdornment position="start">
                  <SearchIcon fontSize="small" />
                </InputAdornment>
              ),
            }}
          />

          {/* Status filter */}
          <FormControl size="small" sx={{ minWidth: 160 }}>
            <InputLabel>Status</InputLabel>
            <Select<StatusEnum[]>
              multiple
              value={selectedStatus}
              onChange={handleStatusChange}
              input={<OutlinedInput label="Status" />}
              renderValue={(selected) =>
                selected.length === 0 ? 'Alle' : `${selected.length} gewählt`
              }
            >
              {STATUS_VALUES.map((s) => (
                <MenuItem key={s} value={s}>
                  {STATUS_LABELS[s]}
                </MenuItem>
              ))}
            </Select>
          </FormControl>

          {/* Dienstgrad filter */}
          <FormControl size="small" sx={{ minWidth: 160 }}>
            <InputLabel>Dienstgrad</InputLabel>
            <Select<DienstgradEnum[]>
              multiple
              value={selectedDienstgrad}
              onChange={handleDienstgradChange}
              input={<OutlinedInput label="Dienstgrad" />}
              renderValue={(selected) =>
                selected.length === 0 ? 'Alle' : `${selected.length} gewählt`
              }
            >
              {DIENSTGRAD_VALUES.map((dg) => (
                <MenuItem key={dg} value={dg}>
                  {dg}
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </Box>

        {/* Active filter chips */}
        {activeFilters > 0 && (
          <Box sx={{ display: 'flex', gap: 1, mb: 2, flexWrap: 'wrap' }}>
            {selectedStatus.map((s) => (
              <Chip
                key={s}
                label={STATUS_LABELS[s]}
                size="small"
                color={STATUS_COLORS[s]}
                onDelete={() => handleRemoveStatusChip(s)}
              />
            ))}
            {selectedDienstgrad.map((dg) => (
              <Chip
                key={dg}
                label={dg}
                size="small"
                onDelete={() => handleRemoveDienstgradChip(dg)}
              />
            ))}
          </Box>
        )}

        {/* Error state */}
        {error && (
          <Alert severity="error" sx={{ mb: 2 }} onClose={() => setError(null)}>
            {error}
          </Alert>
        )}

        {/* Table */}
        <Paper sx={{ width: '100%', overflow: 'hidden' }}>
          <TablePagination
            component="div"
            count={total}
            page={page}
            onPageChange={(_e, newPage) => setPage(newPage)}
            rowsPerPage={pageSize}
            rowsPerPageOptions={[25, 50, 100, { value: -1, label: 'Alle' }]}
            onRowsPerPageChange={(e) => {
              setPageSize(parseInt(e.target.value, 10));
              setPage(0);
            }}
            labelRowsPerPage="Einträge pro Seite:"
            labelDisplayedRows={({ from, to, count }) =>
              `${from}–${to} von ${count !== -1 ? count : `mehr als ${to}`}`
            }
          />
          <DataTable<MemberListItem>
            columns={[
              { key: 'profile_picture_url', label: 'Foto', width: 56, sortable: false, searchable: false, render: (member) => {
                const displayName = getMemberDisplayName(member);
                const initials = [member.given_name?.[0], member.family_name?.[0]]
                  .filter(Boolean).join('').toUpperCase() || member.email[0].toUpperCase();
                return (
                  <Avatar src={member.profile_picture_url ?? undefined} alt={displayName} sx={{ width: 36, height: 36, fontSize: '0.875rem' }}>
                    {initials}
                  </Avatar>
                );
              }},
              { key: 'family_name', label: 'Name', render: (member) => {
                const displayName = getMemberDisplayName(member);
                return (
                  <Box>
                    <Typography variant="body2" fontWeight={500}>{displayName}</Typography>
                    <Typography variant="caption" color="text.secondary">{member.email}</Typography>
                  </Box>
                );
              }},
              { key: 'fdisk_standesbuch_nr', label: 'Stundenbuchnr.', render: (member) => member.fdisk_standesbuch_nr ?? '—' },
              { key: 'dienstgrad', label: 'Dienstgrad', render: (member) => member.dienstgrad
                ? <Chip label={member.dienstgrad} size="small" variant="outlined" />
                : <Typography variant="body2" color="text.secondary">—</Typography>
              },
              { key: 'funktion', label: 'Funktion', sortable: false, render: (member) => (
                <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>
                  {Array.isArray(member.funktion) && member.funktion.length > 0
                    ? member.funktion.map((f) => <Chip key={f} label={f} size="small" variant="outlined" color="secondary" />)
                    : <Typography variant="body2" color="text.secondary">—</Typography>
                  }
                </Box>
              )},
              { key: 'status', label: 'Status', render: (member) => member.status
                ? <StatusChip status={member.status} labelMap={STATUS_LABELS} colorMap={STATUS_COLORS} />
                : <Typography variant="body2" color="text.secondary">—</Typography>
              },
              { key: 'eintrittsdatum', label: 'Eintrittsdatum', render: (member) => member.eintrittsdatum
                ? new Date(member.eintrittsdatum).toLocaleDateString('de-AT')
                : '—'
              },
              { key: 'telefon_mobil', label: 'Telefon', render: (member) => formatPhone(member.telefon_mobil) },
            ]}
            data={members}
            rowKey={(member) => member.id}
            onRowClick={(member) => handleRowClick(member.id)}
            isLoading={loading}
            emptyMessage="Keine Mitglieder gefunden."
            emptyIcon={<PeopleIcon sx={{ fontSize: 40, mb: 1, opacity: 0.5 }} />}
            searchEnabled={false}
            paginationEnabled={false}
            stickyHeader
          />
          <TablePagination
            component="div"
            count={total}
            page={page}
            onPageChange={(_e, newPage) => setPage(newPage)}
            rowsPerPage={pageSize}
            rowsPerPageOptions={[25, 50, 100, { value: -1, label: 'Alle' }]}
            onRowsPerPageChange={(e) => {
              setPageSize(parseInt(e.target.value, 10));
              setPage(0);
            }}
            labelRowsPerPage="Einträge pro Seite:"
            labelDisplayedRows={({ from, to, count }) =>
              `${from}–${to} von ${count !== -1 ? count : `mehr als ${to}`}`
            }
          />

        </Paper>
      </Container>

      {/* FAB — only visible to Kommandant/Admin */}
      {canWrite && (
        <Tooltip title="Neues Mitglied anlegen">
          <ChatAwareFab
            aria-label="Neues Mitglied anlegen"
            onClick={() => navigate('/mitglieder/neu')}
            sx={{ zIndex: (theme) => theme.zIndex.speedDial }}
          >
            <AddIcon />
          </ChatAwareFab>
        </Tooltip>
      )}
    </DashboardLayout>
  );
}

export default Mitglieder;
