import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Key,
  Plus,
  Copy,
  Check,
  Trash2,
  Eye,
  EyeOff,
  Clock,
  Shield,
  AlertTriangle,
  ExternalLink,
  ChevronDown,
  ChevronUp,
  X,
} from 'lucide-react';
import {
  useApiTokens,
  useCreateApiToken,
  useRevokeApiToken,
  useUpdateApiToken,
  API_SCOPES,
  SCOPE_PRESETS,
  APIToken,
  APITokenCreateResponse,
} from '../hooks/useApiTokens';

interface NewTokenModalProps {
  isOpen: boolean;
  onClose: () => void;
  onTokenCreated: (token: APITokenCreateResponse) => void;
}

const NewTokenModal: React.FC<NewTokenModalProps> = ({ isOpen, onClose, onTokenCreated }) => {
  const { t } = useTranslation();
  const [name, setName] = useState('');
  const [selectedScopes, setSelectedScopes] = useState<string[]>([]);
  const [expiresIn, setExpiresIn] = useState<string>('never');
  const [showAdvanced, setShowAdvanced] = useState(false);
  const createMutation = useCreateApiToken();

  const handlePresetSelect = (presetKey: keyof typeof SCOPE_PRESETS) => {
    setSelectedScopes(SCOPE_PRESETS[presetKey].scopes);
  };

  const toggleScope = (scope: string) => {
    setSelectedScopes(prev =>
      prev.includes(scope)
        ? prev.filter(s => s !== scope)
        : [...prev, scope]
    );
  };

  const calculateExpiryDate = (): string | null => {
    if (expiresIn === 'never') return null;
    const now = new Date();
    switch (expiresIn) {
      case '7d':
        now.setDate(now.getDate() + 7);
        break;
      case '30d':
        now.setDate(now.getDate() + 30);
        break;
      case '90d':
        now.setDate(now.getDate() + 90);
        break;
      case '1y':
        now.setFullYear(now.getFullYear() + 1);
        break;
      default:
        return null;
    }
    return now.toISOString();
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!name.trim() || selectedScopes.length === 0) return;

    try {
      const result = await createMutation.mutateAsync({
        name: name.trim(),
        scopes: selectedScopes,
        expires_at: calculateExpiryDate(),
      });
      onTokenCreated(result);
      setName('');
      setSelectedScopes([]);
      setExpiresIn('never');
    } catch (error) {
      console.error('Failed to create token:', error);
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto">
        <div className="p-6 border-b border-gray-200 dark:border-gray-700">
          <div className="flex items-center justify-between">
            <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
              Create API Token
            </h2>
            <button
              onClick={onClose}
              className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700"
            >
              <X size={20} />
            </button>
          </div>
        </div>

        <form onSubmit={handleSubmit} className="p-6 space-y-6">
          {/* Token Name */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
              Token Name
            </label>
            <input
              type="text"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="e.g., Website Integration, Mobile App"
              className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-transparent"
              required
            />
            <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
              Choose a descriptive name to identify this token's purpose
            </p>
          </div>

          {/* Scope Presets */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
              Permission Presets
            </label>
            <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
              {Object.entries(SCOPE_PRESETS).map(([key, preset]) => (
                <button
                  key={key}
                  type="button"
                  onClick={() => handlePresetSelect(key as keyof typeof SCOPE_PRESETS)}
                  className={`p-3 text-left border rounded-lg transition-colors ${
                    JSON.stringify(selectedScopes.sort()) === JSON.stringify(preset.scopes.sort())
                      ? 'border-purple-500 bg-brand-50 dark:bg-brand-900/20'
                      : 'border-gray-200 dark:border-gray-600 hover:border-purple-300 dark:hover:border-purple-700'
                  }`}
                >
                  <div className="font-medium text-gray-900 dark:text-white text-sm">
                    {preset.label}
                  </div>
                  <div className="text-xs text-gray-500 dark:text-gray-400 mt-1">
                    {preset.description}
                  </div>
                </button>
              ))}
            </div>
          </div>

          {/* Advanced: Individual Scopes */}
          <div>
            <button
              type="button"
              onClick={() => setShowAdvanced(!showAdvanced)}
              className="flex items-center gap-2 text-sm text-brand-600 dark:text-brand-400 hover:text-brand-700 dark:hover:text-brand-300"
            >
              {showAdvanced ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
              {showAdvanced ? 'Hide' : 'Show'} individual permissions
            </button>

            {showAdvanced && (
              <div className="mt-3 p-4 bg-gray-50 dark:bg-gray-900 rounded-lg space-y-2">
                {API_SCOPES.map((scope) => (
                  <label
                    key={scope.value}
                    className="flex items-start gap-3 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer"
                  >
                    <input
                      type="checkbox"
                      checked={selectedScopes.includes(scope.value)}
                      onChange={() => toggleScope(scope.value)}
                      className="mt-1 h-4 w-4 text-brand-600 border-gray-300 rounded focus:ring-brand-500"
                    />
                    <div>
                      <div className="text-sm font-medium text-gray-900 dark:text-white">
                        {scope.label}
                      </div>
                      <div className="text-xs text-gray-500 dark:text-gray-400">
                        {scope.description}
                      </div>
                    </div>
                  </label>
                ))}
              </div>
            )}
          </div>

          {/* Expiration */}
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
              Expiration
            </label>
            <select
              value={expiresIn}
              onChange={(e) => setExpiresIn(e.target.value)}
              className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-brand-500 focus:border-transparent"
            >
              <option value="never">Never expires</option>
              <option value="7d">7 days</option>
              <option value="30d">30 days</option>
              <option value="90d">90 days</option>
              <option value="1y">1 year</option>
            </select>
          </div>

          {/* Selected Scopes Summary */}
          {selectedScopes.length > 0 && (
            <div className="p-3 bg-brand-50 dark:bg-brand-900/20 rounded-lg">
              <div className="text-sm font-medium text-brand-700 dark:text-brand-300 mb-2">
                Selected permissions ({selectedScopes.length})
              </div>
              <div className="flex flex-wrap gap-1">
                {selectedScopes.map((scope) => (
                  <span
                    key={scope}
                    className="px-2 py-0.5 text-xs bg-brand-100 dark:bg-brand-800 text-brand-700 dark:text-brand-300 rounded"
                  >
                    {scope}
                  </span>
                ))}
              </div>
            </div>
          )}

          {/* Actions */}
          <div className="flex justify-end gap-3 pt-4 border-t border-gray-200 dark:border-gray-700">
            <button
              type="button"
              onClick={onClose}
              className="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={!name.trim() || selectedScopes.length === 0 || createMutation.isPending}
              className="px-4 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
            >
              {createMutation.isPending ? (
                <>
                  <span className="animate-spin">⏳</span>
                  Creating...
                </>
              ) : (
                <>
                  <Key size={16} />
                  Create Token
                </>
              )}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

interface TokenCreatedModalProps {
  token: APITokenCreateResponse | null;
  onClose: () => void;
}

const TokenCreatedModal: React.FC<TokenCreatedModalProps> = ({ token, onClose }) => {
  const [copied, setCopied] = useState(false);
  const [showToken, setShowToken] = useState(false);

  const handleCopy = () => {
    if (token) {
      navigator.clipboard.writeText(token.key);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  if (!token) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
      <div className="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-lg w-full mx-4">
        <div className="p-6">
          <div className="flex items-center gap-3 mb-4">
            <div className="p-2 bg-green-100 dark:bg-green-900/30 rounded-lg">
              <Check className="text-green-600 dark:text-green-400" size={24} />
            </div>
            <div>
              <h2 className="text-xl font-semibold text-gray-900 dark:text-white">
                Token Created
              </h2>
              <p className="text-sm text-gray-500 dark:text-gray-400">
                {token.name}
              </p>
            </div>
          </div>

          <div className="p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg mb-4">
            <div className="flex items-start gap-2">
              <AlertTriangle className="text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" size={18} />
              <div className="text-sm text-yellow-800 dark:text-yellow-200">
                <strong>Important:</strong> Copy your token now. You won't be able to see it again!
              </div>
            </div>
          </div>

          <div className="mb-6">
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
              Your API Token
            </label>
            <div className="flex items-center gap-2">
              <div className="flex-1 relative">
                <input
                  type={showToken ? 'text' : 'password'}
                  value={token.key}
                  readOnly
                  className="w-full px-4 py-3 pr-20 font-mono text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white"
                />
                <button
                  type="button"
                  onClick={() => setShowToken(!showToken)}
                  className="absolute right-2 top-1/2 -translate-y-1/2 p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
                >
                  {showToken ? <EyeOff size={18} /> : <Eye size={18} />}
                </button>
              </div>
              <button
                onClick={handleCopy}
                className={`px-4 py-3 rounded-lg font-medium text-sm transition-colors flex items-center gap-2 ${
                  copied
                    ? 'bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400'
                    : 'bg-brand-600 hover:bg-brand-700 text-white'
                }`}
              >
                {copied ? <Check size={18} /> : <Copy size={18} />}
                {copied ? 'Copied!' : 'Copy'}
              </button>
            </div>
          </div>

          <div className="flex justify-end">
            <button
              onClick={onClose}
              className="px-4 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition-colors"
            >
              Done
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

interface TokenRowProps {
  token: APIToken;
  onRevoke: (id: string, name: string) => void;
  isRevoking: boolean;
}

const TokenRow: React.FC<TokenRowProps> = ({ token, onRevoke, isRevoking }) => {
  const [expanded, setExpanded] = useState(false);

  const formatDate = (dateString: string | null) => {
    if (!dateString) return 'Never';
    return new Date(dateString).toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  };

  const isExpired = token.expires_at && new Date(token.expires_at) < new Date();

  return (
    <div className={`border rounded-lg ${
      !token.is_active || isExpired
        ? 'border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50 opacity-60'
        : 'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800'
    }`}>
      <div className="p-4">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <div className={`p-2 rounded-lg ${
              token.is_active && !isExpired
                ? 'bg-brand-100 dark:bg-brand-900/30'
                : 'bg-gray-100 dark:bg-gray-800'
            }`}>
              <Key size={18} className={
                token.is_active && !isExpired
                  ? 'text-brand-600 dark:text-brand-400'
                  : 'text-gray-400'
              } />
            </div>
            <div>
              <div className="flex items-center gap-2">
                <span className="font-medium text-gray-900 dark:text-white">
                  {token.name}
                </span>
                {(!token.is_active || isExpired) && (
                  <span className="px-2 py-0.5 text-xs font-medium bg-red-100 dark:bg-red-900/30 text-red-700 dark:text-red-400 rounded">
                    {isExpired ? 'Expired' : 'Revoked'}
                  </span>
                )}
              </div>
              <div className="text-sm text-gray-500 dark:text-gray-400 font-mono">
                {token.key_prefix}••••••••
              </div>
            </div>
          </div>

          <div className="flex items-center gap-2">
            <button
              onClick={() => setExpanded(!expanded)}
              className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg"
            >
              {expanded ? <ChevronUp size={18} /> : <ChevronDown size={18} />}
            </button>
            {token.is_active && !isExpired && (
              <button
                onClick={() => onRevoke(token.id, token.name)}
                disabled={isRevoking}
                className="p-2 text-red-400 hover:text-red-600 dark:hover:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg disabled:opacity-50"
                title="Revoke token"
              >
                <Trash2 size={18} />
              </button>
            )}
          </div>
        </div>

        {expanded && (
          <div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700 space-y-3">
            <div className="grid grid-cols-2 gap-4 text-sm">
              <div>
                <div className="text-gray-500 dark:text-gray-400">Created</div>
                <div className="text-gray-900 dark:text-white">{formatDate(token.created_at)}</div>
              </div>
              <div>
                <div className="text-gray-500 dark:text-gray-400">Last Used</div>
                <div className="text-gray-900 dark:text-white">{formatDate(token.last_used_at)}</div>
              </div>
              <div>
                <div className="text-gray-500 dark:text-gray-400">Expires</div>
                <div className={`${isExpired ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-white'}`}>
                  {formatDate(token.expires_at)}
                </div>
              </div>
              {token.created_by && (
                <div>
                  <div className="text-gray-500 dark:text-gray-400">Created By</div>
                  <div className="text-gray-900 dark:text-white">{token.created_by.full_name || token.created_by.username}</div>
                </div>
              )}
            </div>

            <div>
              <div className="text-sm text-gray-500 dark:text-gray-400 mb-2">Permissions</div>
              <div className="flex flex-wrap gap-1">
                {token.scopes.map((scope) => (
                  <span
                    key={scope}
                    className="px-2 py-0.5 text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded"
                  >
                    {scope}
                  </span>
                ))}
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

const ApiTokensSection: React.FC = () => {
  const { t } = useTranslation();
  const { data: tokens, isLoading, error } = useApiTokens();
  const revokeMutation = useRevokeApiToken();
  const [showNewTokenModal, setShowNewTokenModal] = useState(false);
  const [createdToken, setCreatedToken] = useState<APITokenCreateResponse | null>(null);
  const [tokenToRevoke, setTokenToRevoke] = useState<{ id: string; name: string } | null>(null);

  const handleTokenCreated = (token: APITokenCreateResponse) => {
    setShowNewTokenModal(false);
    setCreatedToken(token);
  };

  const handleRevokeClick = (id: string, name: string) => {
    setTokenToRevoke({ id, name });
  };

  const confirmRevoke = async () => {
    if (!tokenToRevoke) return;
    setTokenToRevoke(null);
    await revokeMutation.mutateAsync(tokenToRevoke.id);
  };

  const activeTokens = tokens?.filter(t => t.is_active) || [];
  const revokedTokens = tokens?.filter(t => !t.is_active) || [];

  return (
    <>
      {/* Revoke Confirmation Modal */}
      {tokenToRevoke && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-md w-full mx-4 p-6">
            <div className="flex items-start gap-4">
              <div className="flex-shrink-0 w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/30 flex items-center justify-center">
                <AlertTriangle size={24} className="text-red-600 dark:text-red-400" />
              </div>
              <div className="flex-1">
                <h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
                  Revoke API Token?
                </h3>
                <p className="text-sm text-gray-600 dark:text-gray-300 mb-1">
                  Are you sure you want to revoke <strong>{tokenToRevoke.name}</strong>?
                </p>
                <p className="text-sm text-gray-500 dark:text-gray-400">
                  This action cannot be undone. Applications using this token will immediately lose access.
                </p>
              </div>
            </div>
            <div className="flex items-center gap-3 mt-6">
              <button
                onClick={() => setTokenToRevoke(null)}
                className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors"
              >
                Cancel
              </button>
              <button
                onClick={confirmRevoke}
                disabled={revokeMutation.isPending}
                className="flex-1 px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 rounded-lg transition-colors disabled:opacity-50"
              >
                {revokeMutation.isPending ? 'Revoking...' : 'Revoke Token'}
              </button>
            </div>
          </div>
        </div>
      )}

      <section className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700 shadow-sm">
        <div className="flex items-center justify-between mb-6">
          <div>
            <h3 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
              <Key size={20} className="text-brand-500" />
              API Tokens
            </h3>
            <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
              Create and manage API tokens for third-party integrations
            </p>
          </div>
          <div className="flex items-center gap-2">
            <a
              href="/help/api"
              className="px-3 py-2 text-sm font-medium text-brand-600 dark:text-brand-400 hover:bg-brand-50 dark:hover:bg-brand-900/20 rounded-lg transition-colors flex items-center gap-2"
            >
              <ExternalLink size={16} />
              API Docs
            </a>
            <button
              onClick={() => setShowNewTokenModal(true)}
              className="px-4 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition-colors flex items-center gap-2"
            >
              <Plus size={16} />
              New Token
            </button>
          </div>
        </div>

        {isLoading ? (
          <div className="flex items-center justify-center py-12">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600"></div>
          </div>
        ) : error ? (
          <div className="p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
            <p className="text-sm text-red-600 dark:text-red-400">
              Failed to load API tokens. Please try again later.
            </p>
          </div>
        ) : tokens && tokens.length === 0 ? (
          <div className="text-center py-12">
            <div className="inline-flex items-center justify-center w-16 h-16 bg-gray-100 dark:bg-gray-700 rounded-full mb-4">
              <Key size={32} className="text-gray-400" />
            </div>
            <h4 className="text-lg font-medium text-gray-900 dark:text-white mb-2">
              No API tokens yet
            </h4>
            <p className="text-sm text-gray-500 dark:text-gray-400 mb-4 max-w-sm mx-auto">
              Create your first API token to start integrating with external services and applications.
            </p>
            <button
              onClick={() => setShowNewTokenModal(true)}
              className="px-4 py-2 text-sm font-medium text-white bg-brand-600 hover:bg-brand-700 rounded-lg transition-colors inline-flex items-center gap-2"
            >
              <Plus size={16} />
              Create API Token
            </button>
          </div>
        ) : (
          <div className="space-y-6">
            {activeTokens.length > 0 && (
              <div className="space-y-3">
                <h4 className="text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2">
                  <Shield size={16} className="text-green-500" />
                  Active Tokens ({activeTokens.length})
                </h4>
                <div className="space-y-2">
                  {activeTokens.map((token) => (
                    <TokenRow
                      key={token.id}
                      token={token}
                      onRevoke={handleRevokeClick}
                      isRevoking={revokeMutation.isPending}
                    />
                  ))}
                </div>
              </div>
            )}

            {revokedTokens.length > 0 && (
              <div className="space-y-3">
                <h4 className="text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2">
                  <Clock size={16} />
                  Revoked Tokens ({revokedTokens.length})
                </h4>
                <div className="space-y-2">
                  {revokedTokens.map((token) => (
                    <TokenRow
                      key={token.id}
                      token={token}
                      onRevoke={handleRevokeClick}
                      isRevoking={revokeMutation.isPending}
                    />
                  ))}
                </div>
              </div>
            )}
          </div>
        )}
      </section>

      {/* Modals */}
      <NewTokenModal
        isOpen={showNewTokenModal}
        onClose={() => setShowNewTokenModal(false)}
        onTokenCreated={handleTokenCreated}
      />
      <TokenCreatedModal
        token={createdToken}
        onClose={() => setCreatedToken(null)}
      />
    </>
  );
};

export default ApiTokensSection;
