import React, { useState, useEffect } from "react";
import {
  Button,
  Modal,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  TextField,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
  Pagination,
  IconButton,
  Checkbox,
  FormControlLabel,
  Chip,
  Box,
  Typography,
  Card,
  CardHeader,
  CardContent,
  Divider,
  Grid,
  TextareaAutosize,
  Popover,
  List,
  ListItem,
  ListItemText,
  ListItemIcon,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  DialogContentText,
  CircularProgress
} from "@mui/material";
import {
  Edit as EditIcon,
  Delete as DeleteIcon,
  Add as AddIcon,
  Menu as MenuIcon,
  Close as CloseIcon,
  Search as SearchIcon,
  LibraryBooks as LibraryBooksIcon,
  CheckCircle as CheckCircleIcon
} from "@mui/icons-material";
import { toast } from "react-toastify";
import * as tokenRegistryAPI from './tokenregistryapi';

function TOKENRegistry() {
  const [tokens, setTokens] = useState([]);
  const [showAddEditModal, setShowAddEditModal] = useState(false);
  const [showGenerateTokenModal, setShowGenerateTokenModal] = useState(false);
  const [newTokenName, setNewTokenName] = useState("");
  const [generatedToken, setGeneratedToken] = useState("");
  const [currentToken, setCurrentToken] = useState({
    id: "",
    tokenName: "",
    tokenValue: "",
    isActive: true,
    scopes: []
  });
  const [currentPage, setCurrentPage] = useState(1);
  const [searchQuery, setSearchQuery] = useState("");
  const [isEditing, setIsEditing] = useState(false);
  const [recordsPerPage, setRecordsPerPage] = useState(10);
  const [visibleColumns, setVisibleColumns] = useState({
    id: true,
    tokenName: true,
    tokenValue: true,
    scopes: true,
    isActive: true,
    actions: true
  });
  const [loading, setLoading] = useState(true);
  const [selectedScope, setSelectedScope] = useState("");
  const [selectedScopes, setSelectedScopes] = useState([]);
  const [availableScopes] = useState([
    { value: 'read', label: 'Read Access' },
    { value: 'write', label: 'Write Access' },
    { value: 'delete', label: 'Delete Access' },
    { value: 'admin', label: 'Admin Access' },
  ]);
  const [anchorEl, setAnchorEl] = useState(null);
  const [columnsAnchorEl, setColumnsAnchorEl] = useState(null);
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
  const [tokenToDelete, setTokenToDelete] = useState(null);

  useEffect(() => {
    fetchTokens();
  }, []);

  const fetchTokens = async () => {
    setLoading(true);
    try {
      const data = await tokenRegistryAPI.fetchAllTokens();
      setTokens(data);
    } catch (error) {
      handleApiError(error, "fetch tokens");
    } finally {
      setLoading(false);
    }
  };

  const handleApiError = (error, action) => {
    if (error.message === 'Unauthorized') {
      toast.error("Your session has expired. Please log in again.");
    } else {
      toast.error(`Failed to ${action}`);
      console.error(`Error ${action}:`, error);
    }
  };

  const toggleColumn = (column) => {
    setVisibleColumns(prev => ({
      ...prev,
      [column]: !prev[column],
    }));
  };

  const handleInputChange = (event) => {
    const { name, value, type, checked } = event.target;
    setCurrentToken(prev => ({
      ...prev,
      [name]: type === "checkbox" ? checked : value
    }));
  };

  const handleSearch = (query) => {
    setSearchQuery(query);
    setCurrentPage(1);
  };

  const handleClose = () => {
    setShowAddEditModal(false);
    setShowGenerateTokenModal(false);
    setGeneratedToken("");
    setNewTokenName("");
    setSelectedScopes([]);
  };

  const handleRecordsPerPageChange = (number) => {
    setRecordsPerPage(number);
    setCurrentPage(1);
    setAnchorEl(null);
  };

  const filteredTokens = tokens.filter(
    (item) =>
      item.tokenName &&
      item.tokenName.toLowerCase().includes(searchQuery.toLowerCase())
  );

  const totalPages = Math.ceil(filteredTokens.length / recordsPerPage);
  const handlePageChange = (event, pageNumber) => {
    setCurrentPage(pageNumber);
  };

  const slicedTokens = filteredTokens.slice(
    (currentPage - 1) * recordsPerPage,
    currentPage * recordsPerPage
  );

  const handleSubmit = async (event) => {
    event.preventDefault();
    try {
      if (isEditing) {
        await tokenRegistryAPI.updateToken(currentToken.id, currentToken);
        toast.success("Token updated successfully!");
      } else {
        await tokenRegistryAPI.createToken(currentToken);
        toast.success("Token added successfully!");
      }
      setShowAddEditModal(false);
      fetchTokens();
    } catch (error) {
      handleApiError(error, isEditing ? "update token" : "add token");
    }
  };

  const openModal = (token = { id: "", tokenName: "", tokenValue: "", isActive: false, scopes: [] }) => {
    setIsEditing(!!token.id);
    setCurrentToken(token);
    setSelectedScopes(token.scopes || []);
    setShowAddEditModal(true);
  };

  const handleDeleteClick = (id) => {
    setTokenToDelete(id);
    setDeleteConfirmOpen(true);
  };

  const handleDeleteConfirm = async () => {
    try {
      await tokenRegistryAPI.deleteToken(tokenToDelete);
      toast.success('Token deleted successfully');
      fetchTokens();
    } catch (error) {
      handleApiError(error, "delete token");
    } finally {
      setDeleteConfirmOpen(false);
      setTokenToDelete(null);
    }
  };

  const addScope = () => {
    if (selectedScope && !selectedScopes.includes(selectedScope)) {
      setSelectedScopes([...selectedScopes, selectedScope]);
      setSelectedScope("");
    }
  };

  const removeScope = (scopeToRemove) => {
    setSelectedScopes(selectedScopes.filter(scope => scope !== scopeToRemove));
  };

  const generateNewToken = async () => {
    if (!newTokenName.trim()) {
      toast.error("Please enter a token name");
      return;
    }

    try {
      const data = await tokenRegistryAPI.generateToken({
        name: newTokenName,
        scopes: selectedScopes
      });
      setGeneratedToken(data.tokenValue);
      toast.success("Token generated successfully!");
      fetchTokens();
    } catch (error) {
      handleApiError(error, "generate token");
    }
  };

  const handleMenuClick = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handleMenuClose = () => {
    setAnchorEl(null);
  };

  const handleColumnsMenuClick = (event) => {
    setColumnsAnchorEl(event.currentTarget);
  };

  const handleColumnsMenuClose = () => {
    setColumnsAnchorEl(null);
  };

  return (
    <Box sx={{ marginTop: "1rem", padding: 2 }}>
      {loading ? (
        <Box display="flex" justifyContent="center" alignItems="center" minHeight="200px">
          <CircularProgress />
        </Box>
      ) : (
        <Box>
          {/* Token Generation Card */}
          <Card sx={{ mb: 4, boxShadow: 3 }}>
            <CardHeader
              title="Token Management"
              action={
                <Button 
                  variant="contained" 
                  onClick={() => setShowGenerateTokenModal(true)}
                  sx={{ backgroundColor: '#1976d2', color: 'white' }}
                >
                  Generate New Token
                </Button>
              }
            />
            <CardContent>
              <Typography variant="body1">
                Manage your API tokens here. Generate new tokens or delete existing ones.
              </Typography>
            </CardContent>
          </Card>

          <Box display="flex" justifyContent="space-between" alignItems="center" mb={4}>
            <Typography variant="h4" component="h1" sx={{ fontWeight: 'bold' }}>
              Token Registry
            </Typography>
          </Box>

          <Grid container spacing={2} alignItems="center" mb={3}>
            <Grid item xs={12} md={8} lg={6}>
              <TextField
                fullWidth
                variant="outlined"
                placeholder="Search"
                value={searchQuery}
                onChange={(e) => handleSearch(e.target.value)}
                InputProps={{
                  startAdornment: (
                    <SearchIcon sx={{ color: 'action.active', mr: 1 }} />
                  ),
                  sx: {
                    borderRadius: '10px',
                    boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.1)',
                  }
                }}
              />
            </Grid>

            <Grid item xs={12} md={4} lg={6} display="flex" justifyContent="flex-end">
              <IconButton
                onClick={() => openModal()}
                color="primary"
                sx={{ mr: 2 }}
              >
                <AddIcon />
              </IconButton>
              <IconButton
                onClick={handleColumnsMenuClick}
                color="primary"
              >
                <MenuIcon />
              </IconButton>
            </Grid>
          </Grid>

          <TableContainer component={Paper} sx={{ boxShadow: 3 }}>
            <Table>
              <TableHead sx={{ backgroundColor: '#f5f5f5' }}>
                <TableRow>
                  {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => (
                    <TableCell key={key}>
                      {key.charAt(0).toUpperCase() + key.slice(1)}
                    </TableCell>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {slicedTokens.length === 0 ? (
                  <TableRow>
                    <TableCell
                      colSpan={Object.keys(visibleColumns).filter(key => visibleColumns[key]).length}
                      align="center"
                    >
                      No Data Available
                    </TableCell>
                  </TableRow>
                ) : (
                  slicedTokens.map((token, index) => (
                    <TableRow key={index} hover>
                      {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => (
                        <TableCell key={key}>
                          {key === "actions" ? (
                            <>
                              <IconButton
                                onClick={() => openModal(token)}
                                color="primary"
                                sx={{ mr: 1 }}
                              >
                                <EditIcon />
                              </IconButton>
                              <IconButton
                                onClick={() => handleDeleteClick(token.id)}
                                color="error"
                              >
                                <DeleteIcon />
                              </IconButton>
                            </>
                          ) : key === "isActive" ? (
                            <Chip
                              label={token.isActive ? "Active" : "Inactive"}
                              color={token.isActive ? "success" : "error"}
                              size="small"
                              sx={{ 
                                backgroundColor: token.isActive ? '#d4f7d4' : '#f7d4d4',
                                color: token.isActive ? 'green' : 'red'
                              }}
                            />
                          ) : key === "scopes" ? (
                            <Box>
                              {token.scopes && token.scopes.map(scope => {
                                const scopeInfo = availableScopes.find(s => s.value === scope);
                                return (
                                  <Chip
                                    key={scope}
                                    label={scopeInfo?.label || scope}
                                    color="primary"
                                    size="small"
                                    sx={{ mr: 1, mb: 1 }}
                                  />
                                );
                              })}
                            </Box>
                          ) : (
                            token[key]
                          )}
                        </TableCell>
                      ))}
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </TableContainer>

          {/* Manage Columns */}
          <Popover
            open={Boolean(columnsAnchorEl)}
            anchorEl={columnsAnchorEl}
            onClose={handleColumnsMenuClose}
            anchorOrigin={{
              vertical: 'bottom',
              horizontal: 'right',
            }}
            transformOrigin={{
              vertical: 'top',
              horizontal: 'right',
            }}
          >
            <List>
              {Object.keys(visibleColumns).map((column) => (
                <ListItem key={column} dense button onClick={() => toggleColumn(column)}>
                  <ListItemIcon>
                    <Checkbox
                      edge="start"
                      checked={visibleColumns[column]}
                      tabIndex={-1}
                      disableRipple
                    />
                  </ListItemIcon>
                  <ListItemText primary={column.charAt(0).toUpperCase() + column.slice(1).toLowerCase()} />
                </ListItem>
              ))}
            </List>
          </Popover>

          {/* Records Per Page */}
          <Box display="flex" justifyContent="flex-end" mt={2}>
            <Button
              variant="outlined"
              startIcon={<LibraryBooksIcon />}
              onClick={handleMenuClick}
              sx={{ border: '2px solid', borderRadius: '8px', boxShadow: 1 }}
            >
              {recordsPerPage}
            </Button>
            <Popover
              open={Boolean(anchorEl)}
              anchorEl={anchorEl}
              onClose={handleMenuClose}
              anchorOrigin={{
                vertical: 'bottom',
                horizontal: 'right',
              }}
              transformOrigin={{
                vertical: 'top',
                horizontal: 'right',
              }}
            >
              <List>
                {[1, 5, 10, 20, 50].map((number) => (
                  <ListItem 
                    key={number} 
                    dense 
                    button 
                    onClick={() => handleRecordsPerPageChange(number)}
                    sx={{ minWidth: '100px' }}
                  >
                    <ListItemText primary={number} />
                    {recordsPerPage === number && <CheckCircleIcon color="primary" />}
                  </ListItem>
                ))}
              </List>
            </Popover>
          </Box>

          <Box display="flex" justifyContent="center" mt={2}>
            <Pagination
              count={totalPages}
              page={currentPage}
              onChange={handlePageChange}
              color="primary"
              showFirstButton
              showLastButton
            />
          </Box>

          {/* Generate Token Modal */}
          <Dialog open={showGenerateTokenModal} onClose={handleClose} fullWidth maxWidth="sm">
            <DialogTitle>
              Generate New Token
              <IconButton
                onClick={handleClose}
                sx={{
                  position: 'absolute',
                  right: 8,
                  top: 8,
                }}
              >
                <CloseIcon />
              </IconButton>
            </DialogTitle>
            <DialogContent>
              <Box component="form" sx={{ mt: 1 }}>
                <TextField
                  margin="normal"
                  fullWidth
                  label="Token Name"
                  value={newTokenName}
                  onChange={(e) => setNewTokenName(e.target.value)}
                  required
                  sx={{ mb: 2 }}
                />

                <Typography variant="subtitle1" gutterBottom>
                  Token Scopes
                </Typography>
                <Box display="flex" alignItems="center" mb={2}>
                  <FormControl fullWidth sx={{ mr: 2 }}>
                    <InputLabel>Select a scope</InputLabel>
                    <Select
                      value={selectedScope}
                      onChange={(e) => setSelectedScope(e.target.value)}
                      label="Select a scope"
                    >
                      <MenuItem value=""><em>Select a scope</em></MenuItem>
                      {availableScopes.map(scope => (
                        <MenuItem key={scope.value} value={scope.value}>
                          {scope.label}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>
                  <Button 
                    variant="outlined" 
                    onClick={addScope}
                    disabled={!selectedScope}
                  >
                    Add Scope
                  </Button>
                </Box>
                <Typography variant="caption" display="block" gutterBottom>
                  Select and add the permissions this token should have
                </Typography>
                
                {/* Display selected scopes as chips */}
                {selectedScopes.length > 0 && (
                  <Box sx={{ mt: 2 }}>
                    {selectedScopes.map(scope => {
                      const scopeInfo = availableScopes.find(s => s.value === scope);
                      return (
                        <Chip
                          key={scope}
                          label={scopeInfo?.label || scope}
                          color="primary"
                          onDelete={() => removeScope(scope)}
                          sx={{ mr: 1, mb: 1 }}
                        />
                      );
                    })}
                  </Box>
                )}

                {generatedToken && (
                  <Box sx={{ mt: 2 }}>
                    <Typography variant="subtitle1" gutterBottom>
                      Generated Token
                    </Typography>
                    <TextareaAutosize
                      minRows={3}
                      value={generatedToken}
                      readOnly
                      style={{ width: '100%', padding: '8px', borderRadius: '4px', borderColor: '#ccc' }}
                    />
                    <Typography variant="caption" display="block" gutterBottom>
                      Copy this token and store it securely. You won't be able to see it again.
                    </Typography>
                  </Box>
                )}
              </Box>
            </DialogContent>
            <DialogActions>
              <Button onClick={handleClose}>Close</Button>
              <Button 
                variant="contained"
                onClick={generateNewToken}
                disabled={!newTokenName.trim()}
              >
                Generate Token
              </Button>
            </DialogActions>
          </Dialog>

          {/* Add/Edit Token Modal */}
          <Dialog open={showAddEditModal} onClose={handleClose} fullWidth maxWidth="sm">
            <DialogTitle>
              {isEditing ? "Edit Token" : "Add Token"}
              <IconButton
                onClick={handleClose}
                sx={{
                  position: 'absolute',
                  right: 8,
                  top: 8,
                }}
              >
                <CloseIcon />
              </IconButton>
            </DialogTitle>
            <DialogContent>
              <Box component="form" onSubmit={handleSubmit} sx={{ mt: 1 }}>
                <TextField
                  margin="normal"
                  fullWidth
                  label="Token Name"
                  name="tokenName"
                  value={currentToken.tokenName}
                  onChange={handleInputChange}
                  required
                  sx={{ mb: 2 }}
                />
                <TextField
                  margin="normal"
                  fullWidth
                  label="Token Value"
                  name="tokenValue"
                  value={currentToken.tokenValue}
                  onChange={handleInputChange}
                  required
                  sx={{ mb: 2 }}
                />

                <Typography variant="subtitle1" gutterBottom>
                  Token Scopes
                </Typography>
                <Box display="flex" alignItems="center" mb={2}>
                  <FormControl fullWidth sx={{ mr: 2 }}>
                    <InputLabel>Select a scope</InputLabel>
                    <Select
                      value={selectedScope}
                      onChange={(e) => setSelectedScope(e.target.value)}
                      label="Select a scope"
                    >
                      <MenuItem value=""><em>Select a scope</em></MenuItem>
                      {availableScopes.map(scope => (
                        <MenuItem key={scope.value} value={scope.value}>
                          {scope.label}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>
                  <Button 
                    variant="outlined" 
                    onClick={() => {
                      if (selectedScope && !currentToken.scopes.includes(selectedScope)) {
                        setCurrentToken(prev => ({
                          ...prev,
                          scopes: [...prev.scopes, selectedScope]
                        }));
                        setSelectedScope("");
                      }
                    }}
                    disabled={!selectedScope}
                  >
                    Add Scope
                  </Button>
                </Box>
                <Typography variant="caption" display="block" gutterBottom>
                  Select and add the permissions this token should have
                </Typography>
                
                {/* Display selected scopes as chips */}
                {currentToken.scopes && currentToken.scopes.length > 0 && (
                  <Box sx={{ mt: 2 }}>
                    {currentToken.scopes.map(scope => {
                      const scopeInfo = availableScopes.find(s => s.value === scope);
                      return (
                        <Chip
                          key={scope}
                          label={scopeInfo?.label || scope}
                          color="primary"
                          onDelete={() => {
                            setCurrentToken(prev => ({
                              ...prev,
                              scopes: prev.scopes.filter(s => s !== scope)
                            }));
                          }}
                          sx={{ mr: 1, mb: 1 }}
                        />
                      );
                    })}
                  </Box>
                )}

                <FormControlLabel
                  control={
                    <Checkbox
                      checked={currentToken.isActive}
                      onChange={handleInputChange}
                      name="isActive"
                      color="primary"
                    />
                  }
                  label="Active?"
                  sx={{ mt: 2 }}
                />
              </Box>
            </DialogContent>
            <DialogActions>
              <Button onClick={handleClose}>Close</Button>
              <Button 
                variant="contained"
                onClick={handleSubmit}
                type="submit"
              >
                {isEditing ? "Update Token" : "Add Token"}
              </Button>
            </DialogActions>
          </Dialog>

          {/* Delete Confirmation Dialog */}
          <Dialog
            open={deleteConfirmOpen}
            onClose={() => setDeleteConfirmOpen(false)}
          >
            <DialogTitle>Confirm Delete</DialogTitle>
            <DialogContent>
              <DialogContentText>
                Are you sure you want to delete this token?
              </DialogContentText>
            </DialogContent>
            <DialogActions>
              <Button onClick={() => setDeleteConfirmOpen(false)}>Cancel</Button>
              <Button onClick={handleDeleteConfirm} color="error" autoFocus>
                Delete
              </Button>
            </DialogActions>
          </Dialog>
        </Box>
      )}
    </Box>
  );
}

export default TOKENRegistry;