/**
 * This file is part of the SplendidBear Websites' projects.
 *
 * Copyright (c) 2026 @ www.splendidbear.org
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

import React, { Fragment, useCallback, useEffect, useState } from 'react';
import Dialog from '@mui/material/Dialog';
import { styled } from '@mui/material/styles';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import { arrayOf, shape, string, bool } from 'prop-types';

const StyledDialog = styled(Dialog)({
  '& .MuiDialog-paper': {
    background: '#0a0e14',
    color: '#e0e0e0',
  },
  '& .MuiTextField-root .MuiInputLabel-root': {
    color: '#9e9e9e',
  },
  '& .MuiTextField-root .MuiOutlinedInput-root': {
    '& fieldset': {
      borderColor: 'rgba(35, 111, 135, 0.5)',
    },
    '&:hover fieldset': {
      borderColor: 'rgba(35, 111, 135, 0.8)',
    },
    '&.Mui-focused fieldset': {
      borderColor: '#236f87',
    },
  },
  '& .MuiTextField-root .MuiOutlinedInput-input': {
    color: '#e0e0e0',
  },
  '& .MuiFormHelperText-root': {
    width: '500px',
    maxWidth: '94vw',
    overflow: 'hidden',
    color: '#e0e0e0',
  },
  '& .MuiBackdrop-root': {
    background: 'rgba(2, 4, 8, 0.88)',
    backdropFilter: 'blur(4px)',
  },
});

const base64ToArrayBuffer = base64 => {
  const binary = atob(base64.replace(/([-_])/g, m => ('-' === m ? '+' : '/')));
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes.buffer;
};

const credentialToJSON = credential => {
  const attestationObject = credential.response.attestationObject;
  const clientDataJSON = credential.response.clientDataJSON;

  return {
    id: credential.id,
    rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))).replace(/([+\/=])/g, m => ('+' === m ? '-' : '/' === m ? '_' : '')),
    type: credential.type,
    response: {
      attestationObject: btoa(String.fromCharCode(...new Uint8Array(attestationObject))).replace(/([+\/=])/g, m => ('+' === m ? '-' : '/' === m ? '_' : '')),
      clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(clientDataJSON))).replace(/([+\/=])/g, m => ('+' === m ? '-' : '/' === m ? '_' : '')),
    },
  };
};

const PasskeyManager = ({ credentials, apiRoutes }) => {
  const [addModalOpen, setAddModalOpen] = useState(false);
  const [renameModalOpen, setRenameModalOpen] = useState(false);
  const [deleteModalOpen, setDeleteModalOpen] = useState(false);
  const [selectedCredential, setSelectedCredential] = useState(null);
  const [passkeyName, setPasskeyName] = useState('');
  const [renameName, setRenameName] = useState('');
  const [status, setStatus] = useState({ type: '', message: '' });
  const [loading, setLoading] = useState(false);
  const [credentialsList, setCredentialsList] = useState(credentials);

  useEffect(() => {
    setCredentialsList(credentials);
  }, [credentials]);

  const showStatus = useCallback((message, type) => {
    setStatus({ message, type });
  }, []);

  const closeAddModal = useCallback(() => {
    setAddModalOpen(false);
    setPasskeyName('');
    setStatus({ type: '', message: '' });
  }, []);

  const openAddModal = useCallback(() => {
    setPasskeyName('');
    setStatus({ type: '', message: '' });
    setAddModalOpen(true);
  }, []);

  const handleAddPasskey = useCallback(async () => {
    if (!passkeyName.trim()) {
      showStatus('Please enter a passkey name', 'error');
      return;
    }

    setLoading(true);
    showStatus('Starting registration...', 'loading');

    try {
      const optionsResponse = await fetch(apiRoutes.registrationBegin, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ credentialName: passkeyName.trim() }),
      });

      if (!optionsResponse.ok) throw new Error('Failed to get registration options');
      const options = await optionsResponse.json();

      showStatus('Please touch your security key or use biometric authentication...', 'loading');

      const publicKey = {
        ...options,
        challenge: base64ToArrayBuffer(options.challenge),
        user: {
          ...options.user,
          id: base64ToArrayBuffer(options.user.id),
        },
        attestation: 'direct',
      };

      const credential = await navigator.credentials.create({ publicKey });

      if (!credential) {
        showStatus('Registration was cancelled', 'error');
        setLoading(false);
        return;
      }

      showStatus('Verifying credential...', 'loading');

      const completeResponse = await fetch(apiRoutes.registrationComplete, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          credential: credentialToJSON(credential),
        }),
      });

      if (!completeResponse.ok) throw new Error('Failed to complete registration');

      showStatus('Passkey registered successfully!', 'success');
      setTimeout(() => window.location.reload(), 1500);
    } catch (error) {
      console.error('Registration error:', error);
      showStatus('Error: ' + error.message, 'error');
    }

    setLoading(false);
  }, [passkeyName, apiRoutes, showStatus]);

  const openRenameModal = useCallback(credential => {
    setSelectedCredential(credential);
    setRenameName(credential.credentialName);
    setStatus({ type: '', message: '' });
    setRenameModalOpen(true);
  }, []);

  const closeRenameModal = useCallback(() => {
    setRenameModalOpen(false);
    setSelectedCredential(null);
    setRenameName('');
    setStatus({ type: '', message: '' });
  }, []);

  const handleRename = useCallback(async () => {
    if (!renameName.trim() || !selectedCredential) {
      showStatus('Please enter a new name', 'error');
      return;
    }

    setLoading(true);

    try {
      const response = await fetch(`${apiRoutes.credentials}/${selectedCredential.id}/rename`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: renameName.trim() }),
      });

      if (!response.ok) throw new Error('Failed to rename passkey');

      window.location.reload();
    } catch (error) {
      console.error('Rename error:', error);
      showStatus('Error: ' + error.message, 'error');
    }

    setLoading(false);
  }, [renameName, selectedCredential, apiRoutes, showStatus]);

  const openDeleteModal = useCallback(credential => {
    setSelectedCredential(credential);
    setDeleteModalOpen(true);
  }, []);

  const closeDeleteModal = useCallback(() => {
    setDeleteModalOpen(false);
    setSelectedCredential(null);
  }, []);

  const handleDelete = useCallback(async () => {
    if (!selectedCredential) return;

    setLoading(true);

    try {
      const response = await fetch(`${apiRoutes.credentials}/${selectedCredential.id}`, {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json' },
      });

      if (response.ok) {
        window.location.reload();
      } else {
        showStatus('Failed to delete passkey', 'error');
      }
    } catch (error) {
      console.error('Delete error:', error);
      showStatus('Error: ' + error.message, 'error');
    }

    setLoading(false);
    setDeleteModalOpen(false);
  }, [selectedCredential, apiRoutes, showStatus]);

  const statusClass = 'error' === status.type
    ? 'registration-status--error'
    : 'success' === status.type
      ? 'registration-status--success'
      : 'loading' === status.type
        ? 'registration-status--loading'
        : '';

  return (
    <div className="passkey-manager">
      <div className="passkey-manager__actions">
        <button className="btn btn--primary" onClick={openAddModal} type="button">
          <i className="fa fa-plus" /> Add Passkey
        </button>
      </div>

      <div className="passkey-manager__list">
        {0 < credentialsList.length ? (
          credentialsList.map(credential => (
            <div key={credential.id} className="passkey-item" data-credential-id={credential.id}>
              <div className="passkey-item__header">
                <div className="passkey-item__info">
                  <h3 className="passkey-item__name">{credential.credentialName}</h3>
                  <p className="passkey-item__meta">
                    Created: {credential.createdAt}
                    {credential.lastUsedAt && (
                      <>
                        <br />Last used: {credential.lastUsedAt}
                      </>
                    )}
                  </p>
                </div>
                <div className="passkey-item__badges">
                  {credential.isBackupEligible && (
                    <span className="badge badge--info" title="This passkey can be backed up">
                      <i className="fa fa-cloud" /> Backup Eligible
                    </span>
                  )}
                  {credential.isBackupAuthenticated && (
                    <span className="badge badge--success" title="This passkey is backed up">
                      <i className="fa fa-check" /> Backed Up
                    </span>
                  )}
                </div>
              </div>
              <div className="passkey-item__actions">
                <button
                  className="btn btn--sm btn--warning"
                  onClick={() => openRenameModal(credential)}
                  type="button"
                >
                  <i className="fa fa-edit" /> Rename
                </button>
                <button
                  className="btn btn--sm btn--danger"
                  onClick={() => openDeleteModal(credential)}
                  type="button"
                >
                  <i className="fa fa-trash" /> Delete
                </button>
              </div>
            </div>
          ))
        ) : (
          <div className="empty-state">
            <i className="fa fa-key empty-state__icon" />
            <p className="empty-state__text">No passkeys registered yet.</p>
            <p className="empty-state__subtext">
              Add your first passkey to get started with secure, passwordless authentication.
            </p>
          </div>
        )}
      </div>

      <StyledDialog open={addModalOpen} onClose={closeAddModal}>
        <DialogTitle>Add New Passkey</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            fullWidth
            id="passkeyName"
            label="Passkey Name"
            placeholder="e.g., My Laptop, iPhone"
            value={passkeyName}
            onChange={e => setPasskeyName(e.target.value)}
            onKeyUp={e => 'Enter' === e.key && handleAddPasskey()}
            margin="dense"
            variant="outlined"
            helperText="Give this passkey a descriptive name to help you remember it."
          />
          {status.message && (
            <div className={`registration-status ${statusClass}`}>
              {status.message}
            </div>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={closeAddModal} disabled={loading}>
            Cancel
          </Button>
          <Button onClick={handleAddPasskey} variant="contained" disabled={loading}>
            Continue
          </Button>
        </DialogActions>
      </StyledDialog>

      <StyledDialog open={renameModalOpen} onClose={closeRenameModal}>
        <DialogTitle>Rename Passkey</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            fullWidth
            id="renamePasskeyName"
            label="New Name"
            value={renameName}
            onChange={e => setRenameName(e.target.value)}
            onKeyUp={e => 'Enter' === e.key && handleRename()}
            margin="dense"
            variant="outlined"
          />
          {status.message && (
            <div className={`registration-status ${statusClass}`}>
              {status.message}
            </div>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={closeRenameModal} disabled={loading}>
            Cancel
          </Button>
          <Button onClick={handleRename} variant="contained" disabled={loading}>
            Rename
          </Button>
        </DialogActions>
      </StyledDialog>

      <StyledDialog open={deleteModalOpen} onClose={closeDeleteModal}>
        <DialogTitle>Delete Passkey</DialogTitle>
        <DialogContent>
          <p>
            Are you sure you want to delete the passkey
            {selectedCredential && (
              <Fragment>
                <strong>{selectedCredential.credentialName}</strong>?
                This action cannot be undone.
              </Fragment>
            )}
          </p>
          {status.message && (
            <div className={`registration-status ${statusClass}`}>
              {status.message}
            </div>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={closeDeleteModal} disabled={loading}>
            Cancel
          </Button>
          <Button onClick={handleDelete} variant="contained" color="error" disabled={loading}>
            Delete
          </Button>
        </DialogActions>
      </StyledDialog>
    </div>
  );
};

export default PasskeyManager;

PasskeyManager.propTypes = {
  credentials: arrayOf(shape({
    id:                    string.isRequired,
    credentialName:        string.isRequired,
    createdAt:             string,
    lastUsedAt:            string,
    isBackupEligible:      bool,
    isBackupAuthenticated: bool,
  })).isRequired,
  apiRoutes: shape({
    credentials:          string.isRequired,
    registrationBegin:    string.isRequired,
    registrationComplete: string.isRequired,
  }).isRequired,
};
