import React, { useState, useEffect } from 'react';
import { User, Mail, Lock, LogOut, CheckCircle, AlertCircle, Loader2, Shield, Crown, Eye, EyeOff, Fingerprint, Plus, Trash2, Monitor, Smartphone, Globe } from 'lucide-react';
import { useVault } from '../contexts/VaultContext';
import { isWebAuthnSupported } from '../lib/webauthn';
import { Card } from './ui/card';

const apiHeaders = () => ({
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${localStorage.getItem('auth_token') ?? ''}`,
});

interface ProfileData {
  id: string;
  username: string;
  email: string;
  role: string;
  communityId: string;
}

interface PasskeyEntry {
  id: string;
  name: string;
  createdAt: string;
}

function passkeyIcon(name: string) {
  const n = name.toLowerCase();
  if (n.includes('iphone') || n.includes('ipad') || n.includes('android')) return Smartphone;
  if (n.includes('windows') || n.includes('macos') || n.includes('linux')) return Monitor;
  return Globe;
}

function base64urlToBuffer(base64url: string): ArrayBuffer {
  const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
  const padded = base64.padEnd(base64.length + (4 - (base64.length % 4)) % 4, '=');
  const binary = atob(padded);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
  return bytes.buffer;
}

function bufferToBase64url(buffer: ArrayBuffer): string {
  const bytes = new Uint8Array(buffer);
  let binary = '';
  for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
  return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}

export const Profile: React.FC = () => {
  const { username: ctxUsername, role: ctxRole, logout } = useVault();

  const [profile, setProfile] = useState<ProfileData | null>(null);
  const [loading, setLoading] = useState(true);

  const [editUsername, setEditUsername] = useState('');
  const [editEmail, setEditEmail] = useState('');
  const [saving, setSaving] = useState(false);
  const [saveMsg, setSaveMsg] = useState<{ ok: boolean; text: string } | null>(null);

  const [oldPassword, setOldPassword] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [confirmNew, setConfirmNew] = useState('');
  const [showOld, setShowOld] = useState(false);
  const [showNew, setShowNew] = useState(false);
  const [pwSaving, setPwSaving] = useState(false);
  const [pwMsg, setPwMsg] = useState<{ ok: boolean; text: string } | null>(null);

  const [passkeys, setPasskeys] = useState<PasskeyEntry[]>([]);
  const [pkLoading, setPkLoading] = useState(false);
  const [pkAdding, setPkAdding] = useState(false);
  const [pkError, setPkError] = useState<string | null>(null);
  const passkeySupported = isWebAuthnSupported();

  const fetchPasskeys = async () => {
    setPkLoading(true);
    try {
      const res = await fetch('/api/auth/passkeys', { headers: apiHeaders() });
      const data = await res.json();
      setPasskeys(data.passkeys ?? []);
    } catch {}
    finally { setPkLoading(false); }
  };

  const handleAddPasskey = async () => {
    setPkError(null);
    setPkAdding(true);
    try {
      const beginRes = await fetch('/api/auth/passkeys/begin', {
        method: 'POST',
        headers: apiHeaders(),
        body: JSON.stringify({}),
      });
      if (!beginRes.ok) throw new Error('Could not start passkey setup');
      const options = await beginRes.json();

      const credential = await navigator.credentials.create({
        publicKey: {
          challenge: base64urlToBuffer(options.challenge),
          rp: options.rp,
          user: {
            id: new TextEncoder().encode(options.user.id),
            name: options.user.name,
            displayName: options.user.displayName,
          },
          pubKeyCredParams: options.pubKeyCredParams as PublicKeyCredentialParameters[],
          timeout: options.timeout,
          attestation: options.attestation as AttestationConveyancePreference,
          authenticatorSelection: options.authenticatorSelection as AuthenticatorSelectionCriteria,
        },
      }) as PublicKeyCredential | null;

      if (!credential) throw new Error('Passkey setup was cancelled');
      const response = credential.response as AuthenticatorAttestationResponse;

      const finishRes = await fetch('/api/auth/passkeys/finish', {
        method: 'POST',
        headers: apiHeaders(),
        body: JSON.stringify({
          id: credential.id,
          rawId: bufferToBase64url(credential.rawId),
          type: credential.type,
          response: {
            attestationObject: bufferToBase64url(response.attestationObject),
            clientDataJSON: bufferToBase64url(response.clientDataJSON),
          },
        }),
      });
      if (!finishRes.ok) throw new Error('Failed to save passkey');
      await fetchPasskeys();
    } catch (err) {
      setPkError((err as Error).message);
    } finally {
      setPkAdding(false);
    }
  };

  const handleDeletePasskey = async (id: string) => {
    try {
      await fetch(`/api/auth/passkeys?id=${id}`, { method: 'DELETE', headers: apiHeaders() });
      setPasskeys(prev => prev.filter(p => p.id !== id));
    } catch {}
  };

  useEffect(() => {
    fetch('/api/auth/profile', { headers: apiHeaders() })
      .then(r => r.json())
      .then((data: ProfileData) => {
        setProfile(data);
        setEditUsername(data.username);
        setEditEmail(data.email ?? '');
      })
      .catch(() => {})
      .finally(() => setLoading(false));
    fetchPasskeys();
  }, []);

  const handleSaveProfile = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaveMsg(null);
    setSaving(true);
    try {
      const res = await fetch('/api/auth/profile', {
        method: 'PUT',
        headers: apiHeaders(),
        body: JSON.stringify({ username: editUsername, email: editEmail }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error ?? 'Update failed');
      if (data.token) localStorage.setItem('auth_token', data.token);
      setProfile(prev => prev ? { ...prev, username: data.username, email: data.email } : prev);
      setSaveMsg({ ok: true, text: 'Profile updated successfully' });
    } catch (err) {
      setSaveMsg({ ok: false, text: (err as Error).message });
    } finally {
      setSaving(false);
    }
  };

  const handleChangePassword = async (e: React.FormEvent) => {
    e.preventDefault();
    setPwMsg(null);
    if (newPassword !== confirmNew) {
      setPwMsg({ ok: false, text: 'Passwords do not match' });
      return;
    }
    setPwSaving(true);
    try {
      const res = await fetch('/api/auth/profile', {
        method: 'PUT',
        headers: apiHeaders(),
        body: JSON.stringify({ oldPassword, newPassword }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error ?? 'Failed to change password');
      if (data.token) localStorage.setItem('auth_token', data.token);
      setOldPassword('');
      setNewPassword('');
      setConfirmNew('');
      setPwMsg({ ok: true, text: 'Password changed successfully' });
    } catch (err) {
      setPwMsg({ ok: false, text: (err as Error).message });
    } finally {
      setPwSaving(false);
    }
  };

  const handleLogout = () => {
    logout();
  };

  const initials = (profile?.username ?? ctxUsername ?? 'U').slice(0, 2).toUpperCase();
  const displayRole = profile?.role ?? ctxRole ?? 'member';

  const roleBadge = displayRole === 'owner'
    ? <span className="flex items-center gap-1 px-2 py-0.5 rounded-md text-[10px] font-black uppercase bg-amber-500/10 text-amber-400 border border-amber-500/20"><Crown className="w-3 h-3" /> Owner</span>
    : <span className="flex items-center gap-1 px-2 py-0.5 rounded-md text-[10px] font-black uppercase bg-muted text-muted-foreground border border-border/50"><Shield className="w-3 h-3" /> {displayRole}</span>;

  if (loading) {
    return (
      <div className="flex items-center justify-center h-64">
        <Loader2 className="w-6 h-6 text-indigo-400 animate-spin" />
      </div>
    );
  }

  return (
    <div className="max-w-2xl mx-auto space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-700">
      {/* Header card */}
      <Card className="border-border/50 bg-card/40 backdrop-blur-xl p-8 overflow-hidden relative group">
        <div className="absolute top-0 right-0 w-32 h-32 -mr-8 -mt-8 bg-primary/10 rounded-full blur-3xl group-hover:scale-110 transition-transform duration-500" />
        <div className="flex items-center gap-6 relative z-10">
          <div className="w-20 h-20 rounded-2xl bg-primary/10 border border-primary/20 flex items-center justify-center text-primary font-black text-2xl shadow-inner shadow-primary/5">
            {initials}
          </div>
          <div>
            <div className="flex items-center gap-3 mb-1">
              <h2 className="text-2xl font-black text-foreground tracking-tight">{profile?.username ?? ctxUsername}</h2>
              {roleBadge}
            </div>
            <p className="text-sm text-muted-foreground font-medium">{profile?.email || 'No email set'}</p>
            <p className="text-[10px] font-bold text-muted-foreground/40 mt-1 font-mono">Community: {profile?.communityId.slice(0, 16)}...</p>
          </div>
        </div>
      </Card>

      {/* Edit profile */}
      <Card className="border-border/50 bg-card/40 backdrop-blur-xl p-8">
        <div className="flex items-center gap-3 mb-8">
          <div className="p-2 bg-primary/10 border border-primary/20 rounded-lg">
            <User className="w-5 h-5 text-primary" />
          </div>
          <div>
            <h3 className="font-black text-lg tracking-tight text-foreground">Profile Details</h3>
            <p className="text-sm text-muted-foreground/70">Update your username and email</p>
          </div>
        </div>

        <form onSubmit={handleSaveProfile} className="space-y-6">
          <div className="space-y-2">
            <label className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/60">Username</label>
            <input
              type="text"
              value={editUsername}
              onChange={e => setEditUsername(e.target.value)}
              className="w-full px-4 py-3 bg-background border border-border/50 rounded-xl text-foreground placeholder:text-muted-foreground/30 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all"
              required
              disabled={saving}
            />
          </div>
          <div className="space-y-2">
            <label className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/60">Email</label>
            <div className="relative">
              <Mail className="w-4 h-4 absolute left-4 top-1/2 -translate-y-1/2 text-muted-foreground/40" />
              <input
                type="email"
                value={editEmail}
                onChange={e => setEditEmail(e.target.value)}
                placeholder="your@email.com"
                className="w-full pl-12 pr-4 py-3 bg-background border border-border/50 rounded-xl text-foreground placeholder:text-muted-foreground/30 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all"
                disabled={saving}
              />
            </div>
          </div>

          {saveMsg && (
            <div className={`p-4 rounded-xl flex items-center gap-3 text-sm font-bold border ${saveMsg.ok ? 'bg-emerald-500/10 border-emerald-500/20 text-emerald-500' : 'bg-destructive/10 border-destructive/20 text-destructive'}`}>
              {saveMsg.ok ? <CheckCircle className="w-5 h-5 flex-shrink-0" /> : <AlertCircle className="w-5 h-5 flex-shrink-0" />}
              {saveMsg.text}
            </div>
          )}

          <button
            type="submit"
            disabled={saving}
            className="px-8 py-3 bg-primary hover:bg-primary/90 disabled:bg-muted disabled:text-muted-foreground text-primary-foreground font-black uppercase tracking-widest rounded-xl transition-all text-xs flex items-center gap-2 shadow-lg shadow-primary/20"
          >
            {saving && <Loader2 className="w-4 h-4 animate-spin" />}
            Save Changes
          </button>
        </form>
      </Card>

      {/* Change password */}
      <Card className="border-border/50 bg-card/40 backdrop-blur-xl p-8">
        <div className="flex items-center gap-3 mb-8">
          <div className="p-2 bg-muted border border-border/50 rounded-lg">
            <Lock className="w-5 h-5 text-muted-foreground/60" />
          </div>
          <div>
            <h3 className="font-black text-lg tracking-tight text-foreground">Change Password</h3>
            <p className="text-sm text-muted-foreground/70">Update your account password</p>
          </div>
        </div>

        <form onSubmit={handleChangePassword} className="space-y-6">
          <div className="space-y-2">
            <label className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/60">Current Password</label>
            <div className="relative">
              <input
                type={showOld ? 'text' : 'password'}
                value={oldPassword}
                onChange={e => setOldPassword(e.target.value)}
                placeholder="Enter current password"
                className="w-full px-4 py-3 pr-12 bg-background border border-border/50 rounded-xl text-foreground placeholder:text-muted-foreground/30 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all"
                required
                disabled={pwSaving}
              />
              <button type="button" onClick={() => setShowOld(!showOld)} className="absolute right-4 top-1/2 -translate-y-1/2 text-muted-foreground/40 hover:text-foreground transition-colors">
                {showOld ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
              </button>
            </div>
          </div>
          <div className="space-y-2">
            <label className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/60">New Password</label>
            <div className="relative">
              <input
                type={showNew ? 'text' : 'password'}
                value={newPassword}
                onChange={e => setNewPassword(e.target.value)}
                placeholder="At least 12 characters"
                className="w-full px-4 py-3 pr-12 bg-background border border-border/50 rounded-xl text-foreground placeholder:text-muted-foreground/30 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all"
                required
                disabled={pwSaving}
              />
              <button type="button" onClick={() => setShowNew(!showNew)} className="absolute right-4 top-1/2 -translate-y-1/2 text-muted-foreground/40 hover:text-foreground transition-colors">
                {showNew ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
              </button>
            </div>
          </div>
          <div className="space-y-2">
            <label className="text-[10px] font-black uppercase tracking-widest text-muted-foreground/60">Confirm New Password</label>
            <input
              type="password"
              value={confirmNew}
              onChange={e => setConfirmNew(e.target.value)}
              placeholder="Repeat new password"
              className="w-full px-4 py-3 bg-background border border-border/50 rounded-xl text-foreground placeholder:text-muted-foreground/30 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent transition-all"
              required
              disabled={pwSaving}
            />
          </div>

          {pwMsg && (
            <div className={`p-4 rounded-xl flex items-center gap-3 text-sm font-bold border ${pwMsg.ok ? 'bg-emerald-500/10 border-emerald-500/20 text-emerald-500' : 'bg-destructive/10 border-destructive/20 text-destructive'}`}>
              {pwMsg.ok ? <CheckCircle className="w-5 h-5 flex-shrink-0" /> : <AlertCircle className="w-5 h-5 flex-shrink-0" />}
              {pwMsg.text}
            </div>
          )}

          <button
            type="submit"
            disabled={pwSaving || !oldPassword || !newPassword || !confirmNew}
            className="px-8 py-3 bg-muted border border-border/50 hover:bg-muted/80 disabled:opacity-50 text-foreground font-black uppercase tracking-widest rounded-xl transition-all text-xs flex items-center gap-2"
          >
            {pwSaving && <Loader2 className="w-4 h-4 animate-spin" />}
            Change Password
          </button>
        </form>
      </Card>

      {/* Passkeys */}
      <Card className="border-border/50 bg-card/40 backdrop-blur-xl p-8">
        <div className="flex items-center justify-between mb-8">
          <div className="flex items-center gap-3">
            <div className="p-2 bg-primary/10 border border-primary/20 rounded-lg">
              <Fingerprint className="w-5 h-5 text-primary" />
            </div>
            <div>
              <h3 className="font-black text-lg tracking-tight text-foreground">Passkeys</h3>
              <p className="text-sm text-muted-foreground/70">Sign in without a password using your device's biometrics or PIN</p>
            </div>
          </div>
          {passkeySupported && (
            <button
              onClick={handleAddPasskey}
              disabled={pkAdding}
              className="flex items-center gap-2 px-4 py-2 bg-primary/10 hover:bg-primary/20 border border-primary/20 text-primary font-black uppercase tracking-widest rounded-xl transition-all text-xs"
            >
              {pkAdding ? <Loader2 className="w-4 h-4 animate-spin" /> : <Plus className="w-4 h-4" />}
              Add Passkey
            </button>
          )}
        </div>

        {pkError && (
          <div className="mb-4 p-3 bg-destructive/10 border border-destructive/20 rounded-xl flex items-center gap-2 text-xs text-destructive">
            <AlertCircle className="w-4 h-4 flex-shrink-0" />
            {pkError}
          </div>
        )}

        {!passkeySupported && (
          <div className="p-4 bg-muted/30 border border-border/50 rounded-xl text-sm text-muted-foreground">
            Your browser does not support passkeys. Try a modern browser like Chrome, Safari, or Edge.
          </div>
        )}

        {passkeySupported && (
          pkLoading ? (
            <div className="flex items-center justify-center py-8">
              <Loader2 className="w-6 h-6 animate-spin text-primary/40" />
            </div>
          ) : passkeys.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-10 gap-3 text-center border-2 border-dashed border-border/40 rounded-2xl">
              <Fingerprint className="w-10 h-10 text-muted-foreground/20" />
              <div>
                <p className="font-bold text-sm text-foreground">No passkeys yet</p>
                <p className="text-xs text-muted-foreground mt-0.5">Add a passkey for each device you want to sign in from.</p>
              </div>
              <button
                onClick={handleAddPasskey}
                disabled={pkAdding}
                className="mt-2 flex items-center gap-2 px-5 py-2.5 bg-primary hover:bg-primary/90 text-primary-foreground font-black uppercase tracking-widest rounded-xl transition-all text-xs shadow-lg shadow-primary/20"
              >
                {pkAdding ? <Loader2 className="w-4 h-4 animate-spin" /> : <Plus className="w-4 h-4" />}
                Add your first passkey
              </button>
            </div>
          ) : (
            <div className="space-y-3">
              {passkeys.map(pk => {
                const Icon = passkeyIcon(pk.name);
                return (
                  <div key={pk.id} className="flex items-center justify-between p-4 bg-muted/20 border border-border/40 rounded-xl group hover:border-border transition-all">
                    <div className="flex items-center gap-4">
                      <div className="w-10 h-10 bg-primary/10 border border-primary/20 rounded-xl flex items-center justify-center flex-shrink-0">
                        <Icon className="w-5 h-5 text-primary" />
                      </div>
                      <div>
                        <p className="font-bold text-sm text-foreground">{pk.name}</p>
                        <p className="text-xs text-muted-foreground mt-0.5">
                          Added {new Date(pk.createdAt).toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric' })}
                        </p>
                      </div>
                    </div>
                    <button
                      onClick={() => handleDeletePasskey(pk.id)}
                      className="opacity-0 group-hover:opacity-100 p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-lg transition-all"
                      title="Remove passkey"
                    >
                      <Trash2 className="w-4 h-4" />
                    </button>
                  </div>
                );
              })}
              <p className="text-xs text-muted-foreground/50 pt-1">
                Add a separate passkey for each device — laptop, phone, tablet.
              </p>
            </div>
          )
        )}
      </Card>

      {/* Danger zone */}
      <Card className="border-destructive/20 bg-destructive/5 p-8 relative overflow-hidden">
        <div className="absolute top-0 left-0 w-1 h-full bg-destructive/40" />
        <h3 className="font-black text-lg text-destructive tracking-tight mb-1">Account</h3>
        <p className="text-sm text-destructive/60 mb-6">End your current session</p>
        <button
          onClick={handleLogout}
          className="flex items-center gap-2 px-6 py-3 bg-destructive/10 hover:bg-destructive/20 border border-destructive/30 text-destructive font-black uppercase tracking-widest rounded-xl transition-all text-xs shadow-lg shadow-destructive/10"
        >
          <LogOut className="w-4 h-4" />
          Log Out
        </button>
      </Card>
    </div>
  );
};