import React, { useState, useEffect } from "react";
import { Button, Dropdown, Modal, Form, Row, Col, InputGroup, FormControl, Card } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faEdit, faTrashAlt, faPlus, faBars, faTimes } from "@fortawesome/free-solid-svg-icons";
import "bootstrap/dist/css/bootstrap.min.css";
import { Table, Pagination, PaginationItem, PaginationLink } from "reactstrap";
import { FaSearch } from "react-icons/fa";
import { BsJournals } from "react-icons/bs";
import { toast } from "react-toastify";
import Spinner from '../../UIComponants/Spinner';
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' },
  ]);

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

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

  const totalPages = Math.ceil(filteredTokens.length / recordsPerPage);
  const handlePageChange = (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 handleDelete = async (id) => {
    if (window.confirm("Are you sure you want to delete this token?")) {
      try {
        await tokenRegistryAPI.deleteToken(id);
        toast.success('Token deleted successfully');
        fetchTokens();
      } catch (error) {
        handleApiError(error, "delete token");
      }
    }
  };

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

  return (
    <div style={{ marginTop: "1rem" }}>
      {loading ? (
        <Spinner />
      ) : (
        <div className="container-fluid mt-5">
          {/* Token Generation Card */}
          <Card className="mb-4 shadow-sm">
            <Card.Header className="d-flex justify-content-between align-items-center">
              <Card.Title>Token Management</Card.Title>
              <Button 
                variant="primary" 
                onClick={() => setShowGenerateTokenModal(true)}
                className="custom_button"
              >
                Generate New Token
              </Button>
            </Card.Header>
            <Card.Body>
              <p>Manage your API tokens here. Generate new tokens or delete existing ones.</p>
            </Card.Body>
          </Card>

          <div className="d-flex justify-content-between align-items-center mb-4">
            <h1 className="title_main">Token Registry</h1>
          </div>

          <Row className="align-items-center my-3">
            <Col xs={12} md={8} lg={6} className="d-flex justify-content-center my-3">
              <InputGroup
                className="search-bar"
                style={{
                  borderRadius: "10px",
                  overflow: "hidden",
                  boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)",
                  width: "100%",
                  maxWidth: "528px",
                }}
              >
                <InputGroup.Text style={{ backgroundColor: "#0E6591", color: "#fff", padding: "10px 15px" }}>
                  <FaSearch />
                </InputGroup.Text>
                <FormControl
                  placeholder="Search"
                  value={searchQuery}
                  onChange={(e) => handleSearch(e.target.value)}
                  style={{ padding: "10px", border: "none" }}
                />
              </InputGroup>
            </Col>

            <Col xs={12} md={4} lg={6} className="d-flex justify-content-end">
              <FontAwesomeIcon
                icon={faPlus}
                onClick={() => openModal()}
                style={{
                  cursor: "pointer",
                  fontSize: "1.5rem",
                  color: "#747264",
                  marginRight: "20px",
                }}
              />
              <FontAwesomeIcon
                icon={faBars}
                style={{
                  cursor: "pointer",
                  fontSize: "1.5rem",
                  color: "#747264",
                }}
              />
            </Col>
          </Row>

          <div className="table-responsive">
            <Table striped responsive hover align="middle" className="table-flush shadow-sm">
              <thead className="custom_header">
                <tr>
                  {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => (
                    <th key={key}>{key.charAt(0).toUpperCase() + key.slice(1)}</th>
                  ))}
                </tr>
              </thead>
              <tbody className="tbody">
                {slicedTokens.length === 0 ? (
                  <tr>
                    <td
                      colSpan={Object.keys(visibleColumns).filter(key => visibleColumns[key]).length}
                      className="text-center"
                    >
                      No Data Available
                    </td>
                  </tr>
                ) : (
                  slicedTokens.map((token, index) => (
                    <tr key={index}>
                      {Object.keys(visibleColumns).filter(key => visibleColumns[key]).map(key => (
                        <td key={key}>
                          {key === "actions" ? (
                            <>
                              <FontAwesomeIcon
                                icon={faEdit}
                                onClick={() => openModal(token)}
                                className="me-2"
                                style={{
                                  cursor: "pointer",
                                  fontSize: "1rem",
                                  color: "green",
                                  marginRight: "15px",
                                }}
                              />
                              <FontAwesomeIcon
                                icon={faTrashAlt}
                                onClick={() => handleDelete(token.id)}
                                style={{
                                  cursor: "pointer",
                                  fontSize: "1rem",
                                  color: "#dc3545",
                                }}
                              />
                            </>
                          ) : key === "isActive" ? (
                            <span
                              className="status"
                              style={{
                                color: token.isActive ? "green" : "red",
                                backgroundColor: token.isActive ? "#d4f7d4" : "#f7d4d4",
                                padding: "4px 8px",
                                borderRadius: "4px",
                                display: "inline-block",
                              }}
                            >
                              {token.isActive ? "Active" : "Inactive"}
                            </span>
                          ) : key === "scopes" ? (
                            <div>
                              {token.scopes && token.scopes.map(scope => {
                                const scopeInfo = availableScopes.find(s => s.value === scope);
                                return (
                                  <span 
                                    key={scope} 
                                    className="badge bg-primary me-1 mb-1"
                                    style={{ fontSize: '0.8rem', padding: '3px 6px' }}
                                  >
                                    {scopeInfo?.label || scope}
                                  </span>
                                );
                              })}
                            </div>
                          ) : (
                            token[key]
                          )}
                        </td>
                      ))}
                    </tr>
                  ))
                )}
              </tbody>
            </Table>
          </div>

          {/* Manage Columns & Records Per Page */}
          <Row className="mt-4">
            <Col md={6} className="d-flex justify-content-start">
              <Dropdown>
                <Dropdown.Toggle variant="outline-primary" className="custom_manage_column_button">
                  Manage Columns
                </Dropdown.Toggle>
                <Dropdown.Menu>
                  {Object.keys(visibleColumns).map((column) => (
                    <Dropdown.Item key={column} onClick={() => toggleColumn(column)}>
                      <Form.Check
                        type="checkbox"
                        label={column.charAt(0).toUpperCase() + column.slice(1).toLowerCase()}
                        checked={visibleColumns[column]}
                        readOnly
                        className="custom-checkbox"
                      />
                    </Dropdown.Item>
                  ))}
                </Dropdown.Menu>
              </Dropdown>
            </Col>

            <Col md={6} className="d-flex justify-content-end">
              <Dropdown>
                <Dropdown.Toggle
                  variant="outline-primary"
                  className="custom_manage_column_button px-4 py-2 border-2 rounded-3 shadow-sm"
                >
                  <BsJournals />
                </Dropdown.Toggle>
                <Dropdown.Menu className="border-0 rounded-3 shadow-lg" align="end">
                  {[1, 5, 10, 20, 50].map((number) => (
                    <Dropdown.Item
                      key={number}
                      onClick={() => handleRecordsPerPageChange(number)}
                      className="text-dark d-flex justify-content-between align-items-center"
                    >
                      <span>{number}</span>
                      <i
                        className="fa fa-check-circle"
                        style={{ display: recordsPerPage === number ? "inline" : "none" }}
                      />
                    </Dropdown.Item>
                  ))}
                </Dropdown.Menu>
              </Dropdown>
            </Col>
          </Row>

          <Pagination className="pagination">
            <PaginationItem disabled={currentPage === 1}>
              <PaginationLink previous onClick={() => handlePageChange(currentPage - 1)} />
            </PaginationItem>
            {[...Array(totalPages)].map((_, index) => (
              <PaginationItem key={index} active={index + 1 === currentPage}>
                <PaginationLink onClick={() => handlePageChange(index + 1)} style={{ color: "#0b6592" }}>
                  {index + 1}
                </PaginationLink>
              </PaginationItem>
            ))}
            <PaginationItem disabled={currentPage === totalPages}>
              <PaginationLink next onClick={() => handlePageChange(currentPage + 1)} />
            </PaginationItem>
          </Pagination>

          {/* Generate Token Modal */}
          <Modal show={showGenerateTokenModal} onHide={handleClose}>
            <Modal.Header>
              <Modal.Title>Generate New Token</Modal.Title>
              <FontAwesomeIcon
                icon={faTimes}
                size="lg"
                onClick={handleClose}
                style={{
                  position: "absolute",
                  top: "25px",
                  right: "25px",
                  cursor: "pointer",
                }}
              />
            </Modal.Header>
            <Modal.Body>
              <Form>
                <Form.Group controlId="formNewTokenName" className="mb-3">
                  <Form.Label>Token Name</Form.Label>
                  <Form.Control
                    type="text"
                    value={newTokenName}
                    onChange={(e) => setNewTokenName(e.target.value)}
                    required
                    className="custom-hover-border"
                    placeholder="Enter a name for the new token"
                  />
                </Form.Group>

                <Form.Group controlId="formTokenScopes" className="mb-3">
                  <Form.Label>Token Scopes</Form.Label>
                  <div className="d-flex">
                    <Form.Select
                      value={selectedScope}
                      onChange={(e) => setSelectedScope(e.target.value)}
                      className="custom-hover-border me-2"
                    >
                      <option value="">Select a scope</option>
                      {availableScopes.map(scope => (
                        <option key={scope.value} value={scope.value}>
                          {scope.label}
                        </option>
                      ))}
                    </Form.Select>
                    <Button 
                      variant="outline-primary" 
                      onClick={addScope}
                      disabled={!selectedScope}
                    >
                      Add Scope
                    </Button>
                  </div>
                  <Form.Text className="text-muted">
                    Select and add the permissions this token should have
                  </Form.Text>
                  
                  {/* Display selected scopes as chips */}
                  {selectedScopes.length > 0 && (
                    <div className="mt-2">
                      {selectedScopes.map(scope => {
                        const scopeInfo = availableScopes.find(s => s.value === scope);
                        return (
                          <span 
                            key={scope} 
                            className="badge bg-primary me-2 mb-2"
                            style={{ fontSize: '0.9rem', padding: '5px 10px' }}
                          >
                            {scopeInfo?.label || scope}
                            <FontAwesomeIcon
                              icon={faTimes}
                              className="ms-2"
                              style={{ cursor: 'pointer' }}
                              onClick={() => removeScope(scope)}
                            />
                          </span>
                        );
                      })}
                    </div>
                  )}
                </Form.Group>

                {generatedToken && (
                  <Form.Group controlId="formGeneratedToken" className="mb-3">
                    <Form.Label>Generated Token</Form.Label>
                    <Form.Control
                      as="textarea"
                      rows={3}
                      value={generatedToken}
                      readOnly
                      className="custom-hover-border"
                    />
                    <Form.Text className="text-muted">
                      Copy this token and store it securely. You won't be able to see it again.
                    </Form.Text>
                  </Form.Group>
                )}
                
                <Modal.Footer>
                  <Button variant="secondary" onClick={handleClose}>
                    Close
                  </Button>
                  <Button 
                    variant="primary" 
                    onClick={generateNewToken}
                    disabled={!newTokenName.trim()}
                  >
                    Generate Token
                  </Button>
                </Modal.Footer>
              </Form>
            </Modal.Body>
          </Modal>

          {/* Add/Edit Token Modal */}
          <Modal show={showAddEditModal} onHide={handleClose}>
            <Modal.Header>
              <Modal.Title>{isEditing ? "Edit Token" : "Add Token"}</Modal.Title>
              <FontAwesomeIcon
                icon={faTimes}
                size="lg"
                onClick={handleClose}
                style={{
                  position: "absolute",
                  top: "25px",
                  right: "25px",
                  cursor: "pointer",
                }}
              />
            </Modal.Header>
            <Modal.Body>
              <Form onSubmit={handleSubmit}>
                <Form.Group controlId="formTokenName" className="mb-3">
                  <Form.Label>Token Name</Form.Label>
                  <Form.Control
                    type="text"
                    name="tokenName"
                    value={currentToken.tokenName}
                    onChange={handleInputChange}
                    required
                    className="custom-hover-border"
                  />
                </Form.Group>
                <Form.Group controlId="formTokenValue" className="mb-3">
                  <Form.Label>Token Value</Form.Label>
                  <Form.Control
                    type="text"
                    name="tokenValue"
                    value={currentToken.tokenValue}
                    onChange={handleInputChange}
                    required
                    className="custom-hover-border"
                  />
                </Form.Group>
                <Form.Group controlId="formTokenScopes" className="mb-3">
                  <Form.Label>Token Scopes</Form.Label>
                  <div className="d-flex">
                    <Form.Select
                      value={selectedScope}
                      onChange={(e) => setSelectedScope(e.target.value)}
                      className="custom-hover-border me-2"
                    >
                      <option value="">Select a scope</option>
                      {availableScopes.map(scope => (
                        <option key={scope.value} value={scope.value}>
                          {scope.label}
                        </option>
                      ))}
                    </Form.Select>
                    <Button 
                      variant="outline-primary" 
                      onClick={() => {
                        if (selectedScope && !currentToken.scopes.includes(selectedScope)) {
                          setCurrentToken(prev => ({
                            ...prev,
                            scopes: [...prev.scopes, selectedScope]
                          }));
                          setSelectedScope("");
                        }
                      }}
                      disabled={!selectedScope}
                    >
                      Add Scope
                    </Button>
                  </div>
                  <Form.Text className="text-muted">
                    Select and add the permissions this token should have
                  </Form.Text>
                  
                  {/* Display selected scopes as chips */}
                  {currentToken.scopes && currentToken.scopes.length > 0 && (
                    <div className="mt-2">
                      {currentToken.scopes.map(scope => {
                        const scopeInfo = availableScopes.find(s => s.value === scope);
                        return (
                          <span 
                            key={scope} 
                            className="badge bg-primary me-2 mb-2"
                            style={{ fontSize: '0.9rem', padding: '5px 10px' }}
                          >
                            {scopeInfo?.label || scope}
                            <FontAwesomeIcon
                              icon={faTimes}
                              className="ms-2"
                              style={{ cursor: 'pointer' }}
                              onClick={() => {
                                setCurrentToken(prev => ({
                                  ...prev,
                                  scopes: prev.scopes.filter(s => s !== scope)
                                }));
                              }}
                            />
                          </span>
                        );
                      })}
                    </div>
                  )}
                </Form.Group>
                <Form.Group controlId="formActive" className="mb-3">
                  <Form.Check
                    type="checkbox"
                    label="Active?"
                    name="isActive"
                    checked={currentToken.isActive}
                    onChange={handleInputChange}
                    className="custom-checkbox"
                  />
                </Form.Group>
                <Modal.Footer>
                  <Button variant="secondary" onClick={handleClose}>
                    Close
                  </Button>
                  <Button variant="primary" type="submit">
                    {isEditing ? "Update Token" : "Add Token"}
                  </Button>
                </Modal.Footer>
              </Form>
            </Modal.Body>
          </Modal>
        </div>
      )}
    </div>
  );
}

export default TOKENRegistry;