'use client';

import { useEffect, useState, useCallback } from 'react';
import {
  KeyRound,
  RefreshCw,
  Plus,
  Eye,
  EyeOff,
  Copy,
  Check,
  Trash2,
  RotateCcw,
  Shield,
  Clock,
  AlertTriangle,
} from 'lucide-react';

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Skeleton } from '@/components/ui/skeleton';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';

interface SecretEntry {
  name: string;
  enabled: boolean;
  createdOn: string | null;
  updatedOn: string | null;
  expiresOn: string | null;
  contentType: string | null;
  tags: Record<string, string>;
}

interface SecretDetail {
  name: string;
  value: string;
  version: string;
  enabled: boolean;
  createdOn: string;
  updatedOn: string;
  expiresOn: string | null;
}

export default function SecretsPage() {
  const [secrets, setSecrets] = useState<SecretEntry[]>([]);
  const [vaultUrl, setVaultUrl] = useState<string>('');
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // View secret
  const [viewingSecret, setViewingSecret] = useState<SecretDetail | null>(null);
  const [viewLoading, setViewLoading] = useState(false);
  const [showValue, setShowValue] = useState(false);
  const [copied, setCopied] = useState(false);

  // Add/Edit dialog
  const [dialogOpen, setDialogOpen] = useState(false);
  const [dialogMode, setDialogMode] = useState<'add' | 'edit' | 'rotate'>('add');
  const [formName, setFormName] = useState('');
  const [formValue, setFormValue] = useState('');
  const [saving, setSaving] = useState(false);

  // Delete confirmation
  const [deleteTarget, setDeleteTarget] = useState<string | null>(null);
  const [deleting, setDeleting] = useState(false);

  const fetchSecrets = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const res = await fetch('/api/ops/secrets');
      if (!res.ok) {
        const json = await res.json();
        throw new Error(json.error || `HTTP ${res.status}`);
      }
      const json = await res.json();
      setSecrets(json.secrets);
      setVaultUrl(json.vaultUrl);
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const handleViewSecret = async (name: string) => {
    try {
      setViewLoading(true);
      setShowValue(false);
      setCopied(false);
      const res = await fetch(`/api/ops/secrets/${encodeURIComponent(name)}`);
      if (!res.ok) throw new Error('Failed to read secret');
      const json = await res.json();
      setViewingSecret(json);
    } catch {
      setViewingSecret(null);
    } finally {
      setViewLoading(false);
    }
  };

  const handleCopy = async () => {
    if (viewingSecret?.value) {
      await navigator.clipboard.writeText(viewingSecret.value);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  const openAddDialog = () => {
    setDialogMode('add');
    setFormName('');
    setFormValue('');
    setDialogOpen(true);
  };

  const openEditDialog = (name: string, currentValue?: string) => {
    setDialogMode('edit');
    setFormName(name);
    setFormValue(currentValue || '');
    setDialogOpen(true);
  };

  const openRotateDialog = (name: string) => {
    setDialogMode('rotate');
    setFormName(name);
    // Generate a random 64-char hex string for rotation
    const array = new Uint8Array(32);
    crypto.getRandomValues(array);
    setFormValue(Array.from(array, b => b.toString(16).padStart(2, '0')).join(''));
    setDialogOpen(true);
  };

  const handleSave = async () => {
    if (!formName || !formValue) return;
    try {
      setSaving(true);
      const res = await fetch('/api/ops/secrets', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: formName, value: formValue }),
      });
      if (!res.ok) {
        const json = await res.json();
        throw new Error(json.error || 'Failed to save');
      }
      setDialogOpen(false);
      setFormName('');
      setFormValue('');
      await fetchSecrets();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!deleteTarget) return;
    try {
      setDeleting(true);
      const res = await fetch(`/api/ops/secrets/${encodeURIComponent(deleteTarget)}`, {
        method: 'DELETE',
      });
      if (!res.ok) throw new Error('Failed to delete');
      setDeleteTarget(null);
      await fetchSecrets();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setDeleting(false);
    }
  };

  const isExpiringSoon = (expiresOn: string | null) => {
    if (!expiresOn) return false;
    const diff = new Date(expiresOn).getTime() - Date.now();
    return diff > 0 && diff < 30 * 24 * 60 * 60 * 1000; // 30 days
  };

  const isExpired = (expiresOn: string | null) => {
    if (!expiresOn) return false;
    return new Date(expiresOn).getTime() < Date.now();
  };

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

  return (
    <div className="flex-1 space-y-4 p-8 pt-6">
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-3xl font-bold tracking-tight">Secrets Manager</h2>
          {vaultUrl && <p className="text-sm text-muted-foreground mt-1 font-mono">{vaultUrl}</p>}
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={fetchSecrets} disabled={loading}>
            <RefreshCw className={`mr-2 h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
            Refresh
          </Button>
          <Button size="sm" onClick={openAddDialog}>
            <Plus className="mr-2 h-4 w-4" />
            Add Secret
          </Button>
        </div>
      </div>

      {/* Error Banner */}
      {error && (
        <Card className="border-red-500/50 bg-red-500/5">
          <CardContent className="p-4 flex items-center gap-3">
            <AlertTriangle className="h-5 w-5 text-red-500 shrink-0" />
            <div>
              <p className="text-sm font-medium text-red-500">Error</p>
              <p className="text-xs text-muted-foreground">{error}</p>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Stats */}
      <div className="grid gap-4 md:grid-cols-3">
        <Card>
          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
            <CardTitle className="text-sm font-medium">Total Secrets</CardTitle>
            <KeyRound className="h-4 w-4 text-muted-foreground" />
          </CardHeader>
          <CardContent>
            <div className="text-2xl font-bold">{secrets.length}</div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
            <CardTitle className="text-sm font-medium">Active</CardTitle>
            <Shield className="h-4 w-4 text-green-500" />
          </CardHeader>
          <CardContent>
            <div className="text-2xl font-bold text-green-500">
              {secrets.filter(s => s.enabled && !isExpired(s.expiresOn)).length}
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
            <CardTitle className="text-sm font-medium">Expiring Soon</CardTitle>
            <Clock className="h-4 w-4 text-yellow-500" />
          </CardHeader>
          <CardContent>
            <div className="text-2xl font-bold text-yellow-500">
              {secrets.filter(s => isExpiringSoon(s.expiresOn)).length}
            </div>
          </CardContent>
        </Card>
      </div>

      {/* Secrets Table */}
      <Card>
        <CardHeader>
          <CardTitle>Vault Secrets</CardTitle>
          <CardDescription>
            Manage secrets stored in Azure Key Vault. Click a row to view its value.
          </CardDescription>
        </CardHeader>
        <CardContent>
          {loading && secrets.length === 0 ? (
            <div className="space-y-3">
              {Array.from({ length: 6 }).map((_, i) => (
                <Skeleton key={i} className="h-10 w-full" />
              ))}
            </div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Name</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Last Updated</TableHead>
                  <TableHead>Expires</TableHead>
                  <TableHead className="text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {secrets.map(secret => (
                  <TableRow key={secret.name} className="cursor-pointer hover:bg-muted/50">
                    <TableCell
                      className="font-mono text-sm font-medium"
                      onClick={() => handleViewSecret(secret.name)}
                    >
                      {secret.name}
                    </TableCell>
                    <TableCell>
                      {isExpired(secret.expiresOn) ? (
                        <Badge variant="destructive">Expired</Badge>
                      ) : !secret.enabled ? (
                        <Badge variant="secondary">Disabled</Badge>
                      ) : isExpiringSoon(secret.expiresOn) ? (
                        <Badge className="bg-yellow-500/10 text-yellow-500 hover:bg-yellow-500/20">
                          Expiring
                        </Badge>
                      ) : (
                        <Badge className="bg-green-500/10 text-green-500 hover:bg-green-500/20">
                          Active
                        </Badge>
                      )}
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {formatDate(secret.updatedOn)}
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {secret.expiresOn ? formatDate(secret.expiresOn) : 'Never'}
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex items-center justify-end gap-1">
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          title="View"
                          onClick={() => handleViewSecret(secret.name)}
                        >
                          <Eye className="h-4 w-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          title="Edit"
                          onClick={() => openEditDialog(secret.name)}
                        >
                          <KeyRound className="h-4 w-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          title="Rotate"
                          onClick={() => openRotateDialog(secret.name)}
                        >
                          <RotateCcw className="h-4 w-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8 text-red-500 hover:text-red-600"
                          title="Delete"
                          onClick={() => setDeleteTarget(secret.name)}
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
                {secrets.length === 0 && !loading && (
                  <TableRow>
                    <TableCell colSpan={5} className="text-center text-muted-foreground py-8">
                      No secrets found in vault
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>

      {/* View Secret Dialog */}
      <Dialog open={viewingSecret !== null} onOpenChange={() => setViewingSecret(null)}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle className="font-mono">{viewingSecret?.name}</DialogTitle>
            <DialogDescription>Secret value from Azure Key Vault</DialogDescription>
          </DialogHeader>
          {viewLoading ? (
            <Skeleton className="h-20 w-full" />
          ) : viewingSecret ? (
            <div className="space-y-4">
              <div className="space-y-2">
                <Label>Value</Label>
                <div className="relative">
                  <Input
                    type={showValue ? 'text' : 'password'}
                    value={viewingSecret.value}
                    readOnly
                    className="pr-20 font-mono text-sm"
                  />
                  <div className="absolute right-1 top-1 flex gap-1">
                    <Button
                      variant="ghost"
                      size="icon"
                      className="h-7 w-7"
                      onClick={() => setShowValue(!showValue)}
                    >
                      {showValue ? (
                        <EyeOff className="h-3.5 w-3.5" />
                      ) : (
                        <Eye className="h-3.5 w-3.5" />
                      )}
                    </Button>
                    <Button variant="ghost" size="icon" className="h-7 w-7" onClick={handleCopy}>
                      {copied ? (
                        <Check className="h-3.5 w-3.5 text-green-500" />
                      ) : (
                        <Copy className="h-3.5 w-3.5" />
                      )}
                    </Button>
                  </div>
                </div>
              </div>
              <div className="grid grid-cols-2 gap-4 text-sm">
                <div>
                  <p className="text-muted-foreground">Version</p>
                  <p className="font-mono text-xs truncate">{viewingSecret.version}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Created</p>
                  <p>{formatDate(viewingSecret.createdOn)}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Updated</p>
                  <p>{formatDate(viewingSecret.updatedOn)}</p>
                </div>
                <div>
                  <p className="text-muted-foreground">Expires</p>
                  <p>{viewingSecret.expiresOn ? formatDate(viewingSecret.expiresOn) : 'Never'}</p>
                </div>
              </div>
            </div>
          ) : null}
          <DialogFooter>
            <Button variant="outline" onClick={() => setViewingSecret(null)}>
              Close
            </Button>
            <Button
              variant="outline"
              onClick={() => {
                if (viewingSecret) {
                  openEditDialog(viewingSecret.name, viewingSecret.value);
                  setViewingSecret(null);
                }
              }}
            >
              Edit Value
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Add / Edit / Rotate Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>
              {dialogMode === 'add'
                ? 'Add Secret'
                : dialogMode === 'edit'
                  ? 'Edit Secret'
                  : 'Rotate Secret'}
            </DialogTitle>
            <DialogDescription>
              {dialogMode === 'add'
                ? 'Create a new secret in Azure Key Vault'
                : dialogMode === 'edit'
                  ? `Update the value for ${formName}`
                  : `Generate a new value for ${formName}`}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Secret Name</Label>
              <Input
                value={formName}
                onChange={e => setFormName(e.target.value)}
                placeholder="e.g. my-new-secret"
                disabled={dialogMode !== 'add'}
                className="font-mono"
              />
            </div>
            <div className="space-y-2">
              <Label>Secret Value</Label>
              <Input
                type="password"
                value={formValue}
                onChange={e => setFormValue(e.target.value)}
                placeholder="Enter secret value"
                className="font-mono"
              />
              {dialogMode === 'rotate' && (
                <p className="text-xs text-muted-foreground">
                  A random 64-character hex value has been generated. Edit or accept.
                </p>
              )}
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)}>
              Cancel
            </Button>
            <Button onClick={handleSave} disabled={saving || !formName || !formValue}>
              {saving ? (
                <RefreshCw className="mr-2 h-4 w-4 animate-spin" />
              ) : dialogMode === 'rotate' ? (
                <RotateCcw className="mr-2 h-4 w-4" />
              ) : (
                <KeyRound className="mr-2 h-4 w-4" />
              )}
              {dialogMode === 'add' ? 'Create' : dialogMode === 'edit' ? 'Update' : 'Rotate'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation Dialog */}
      <Dialog open={deleteTarget !== null} onOpenChange={() => setDeleteTarget(null)}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle className="text-red-500">Delete Secret</DialogTitle>
            <DialogDescription>
              Are you sure you want to delete{' '}
              <span className="font-mono font-bold">{deleteTarget}</span>? This will soft-delete the
              secret in Azure Key Vault. It can be recovered within the retention period.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Cancel
            </Button>
            <Button variant="destructive" onClick={handleDelete} disabled={deleting}>
              {deleting && <RefreshCw className="mr-2 h-4 w-4 animate-spin" />}
              Delete
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
