"use client";

import { useState, useEffect, useCallback } from "react";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Eye, EyeOff, Copy, Check } from "lucide-react";
import type { Credential } from "@/lib/api/credentials";
import { getExpiryStatus } from "@/lib/api/credentials";

interface ViewCredentialDialogProps {
  credential: Credential | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onRevealValue: (id: string) => Promise<string>;
}

const AUTO_HIDE_DURATION_MS = 30000; // 30 seconds

export function ViewCredentialDialog({
  credential,
  open,
  onOpenChange,
  onRevealValue,
}: ViewCredentialDialogProps): React.ReactElement {
  const [isRevealing, setIsRevealing] = useState(false);
  const [revealedValue, setRevealedValue] = useState<string | null>(null);
  const [showWarning, setShowWarning] = useState(false);
  const [autoHideTimer, setAutoHideTimer] = useState<number | null>(null);
  const [copied, setCopied] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Cleanup on unmount or dialog close
  useEffect(() => {
    if (!open) {
      setRevealedValue(null);
      setShowWarning(false);
      setError(null);
      if (autoHideTimer) {
        clearTimeout(autoHideTimer);
        setAutoHideTimer(null);
      }
    }
  }, [open, autoHideTimer]);

  const handleRevealClick = useCallback((): void => {
    setShowWarning(true);
  }, []);

  const handleConfirmReveal = useCallback(async (): Promise<void> => {
    if (!credential) return;

    setIsRevealing(true);
    setError(null);
    setShowWarning(false);

    try {
      const value = await onRevealValue(credential.id);
      setRevealedValue(value);

      // Auto-hide after 30 seconds
      const timerId = window.setTimeout(() => {
        setRevealedValue(null);
        setAutoHideTimer(null);
      }, AUTO_HIDE_DURATION_MS);
      setAutoHideTimer(timerId);
    } catch (err) {
      setError(
        err instanceof Error
          ? err.message
          : "Failed to reveal credential. You may have exceeded the rate limit (10 requests/minute)."
      );
    } finally {
      setIsRevealing(false);
    }
  }, [credential, onRevealValue]);

  const handleCopy = useCallback(async (): Promise<void> => {
    if (!revealedValue) return;

    try {
      await navigator.clipboard.writeText(revealedValue);
      setCopied(true);
      setTimeout(() => {
        setCopied(false);
      }, 2000);
    } catch (err) {
      console.error("Failed to copy:", err);
    }
  }, [revealedValue]);

  const handleHideValue = useCallback((): void => {
    setRevealedValue(null);
    if (autoHideTimer) {
      clearTimeout(autoHideTimer);
      setAutoHideTimer(null);
    }
  }, [autoHideTimer]);

  if (!credential) return <></>;

  const expiryInfo = getExpiryStatus(credential.expiresAt);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[525px]">
        <DialogHeader>
          <DialogTitle>{credential.name}</DialogTitle>
          <DialogDescription>View credential details and reveal value</DialogDescription>
        </DialogHeader>

        <div className="grid gap-4 py-4">
          {/* Provider & Type */}
          <div className="flex gap-4">
            <div>
              <p className="text-sm text-muted-foreground">Provider</p>
              <Badge variant="outline" className="mt-1">
                {credential.provider}
              </Badge>
            </div>
            <div>
              <p className="text-sm text-muted-foreground">Type</p>
              <Badge variant="outline" className="mt-1">
                {credential.type.replace(/_/g, " ")}
              </Badge>
            </div>
          </div>

          {/* Description */}
          {credential.description && (
            <div>
              <p className="text-sm text-muted-foreground">Description</p>
              <p className="mt-1 text-sm">{credential.description}</p>
            </div>
          )}

          {/* Masked Value */}
          <div>
            <p className="text-sm text-muted-foreground">Masked Value</p>
            <code className="mt-1 block rounded bg-muted px-3 py-2 font-mono text-sm">
              {credential.maskedValue ?? "••••••••"}
            </code>
          </div>

          {/* Revealed Value */}
          {revealedValue && (
            <div className="rounded-lg border border-orange-200 bg-orange-50 p-4">
              <div className="mb-2 flex items-center justify-between">
                <p className="text-sm font-medium text-orange-900">Decrypted Value</p>
                <div className="flex gap-2">
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={handleCopy}
                    className="h-8 text-orange-900 hover:bg-orange-100"
                  >
                    {copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
                  </Button>
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={handleHideValue}
                    className="h-8 text-orange-900 hover:bg-orange-100"
                  >
                    <EyeOff className="h-4 w-4" />
                  </Button>
                </div>
              </div>
              <code className="block rounded bg-white px-3 py-2 font-mono text-sm text-orange-900 break-all">
                {revealedValue}
              </code>
              <p className="mt-2 text-xs text-orange-700">Value will auto-hide in 30 seconds</p>
            </div>
          )}

          {/* Warning before reveal */}
          {showWarning && !revealedValue && (
            <div className="rounded-lg border border-yellow-200 bg-yellow-50 p-4">
              <p className="mb-2 text-sm font-medium text-yellow-900">Reveal Credential Value?</p>
              <p className="mb-4 text-sm text-yellow-700">
                This will decrypt and display the credential value in plaintext. This action is
                logged. The value will auto-hide after 30 seconds.
              </p>
              <div className="flex gap-2">
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => {
                    setShowWarning(false);
                  }}
                  disabled={isRevealing}
                >
                  Cancel
                </Button>
                <Button size="sm" onClick={handleConfirmReveal} disabled={isRevealing}>
                  {isRevealing ? "Revealing..." : "Confirm Reveal"}
                </Button>
              </div>
            </div>
          )}

          {/* Reveal Button */}
          {!showWarning && !revealedValue && (
            <Button onClick={handleRevealClick} variant="outline" className="w-full">
              <Eye className="mr-2 h-4 w-4" />
              Reveal Value
            </Button>
          )}

          {/* Error Display */}
          {error && (
            <div className="rounded-lg border border-destructive/50 bg-destructive/10 p-3">
              <p className="text-sm text-destructive">{error}</p>
            </div>
          )}

          {/* Expiry Status */}
          {credential.expiresAt && (
            <div>
              <p className="text-sm text-muted-foreground">Target Date</p>
              <div className="mt-1 flex items-center gap-2">
                <Badge variant="outline" className={expiryInfo.className}>
                  {expiryInfo.label}
                </Badge>
                <span className="text-sm text-muted-foreground">
                  {new Date(credential.expiresAt).toLocaleDateString()}
                </span>
              </div>
            </div>
          )}

          {/* Last Used */}
          {credential.lastUsedAt && (
            <div>
              <p className="text-sm text-muted-foreground">Last Used</p>
              <p className="mt-1 text-sm">{new Date(credential.lastUsedAt).toLocaleString()}</p>
            </div>
          )}

          {/* Metadata */}
          {credential.rotatedAt && (
            <div>
              <p className="text-sm text-muted-foreground">Last Rotated</p>
              <p className="mt-1 text-sm">{new Date(credential.rotatedAt).toLocaleString()}</p>
            </div>
          )}
        </div>
      </DialogContent>
    </Dialog>
  );
}
