import { useState, useRef, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useAuthStore } from '../stores/auth.ts';
import { usePushStore } from '../stores/push.ts';

export function UserSettings() {
  const { user, updateProfile, changePassword, isLoading, error, clearError } = useAuthStore();
  const { isSupported, isSubscribed, subscribe, unsubscribe, checkSubscription } = usePushStore();
  const navigate = useNavigate();

  const [displayName, setDisplayName] = useState('');
  const [bio, setBio] = useState('');
  const [statusText, setStatusText] = useState('');
  const [accentColor, setAccentColor] = useState('#fe8019');
  const [saved, setSaved] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Password change state
  const [currentPassword, setCurrentPassword] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [confirmNewPassword, setConfirmNewPassword] = useState('');
  const [passwordLoading, setPasswordLoading] = useState(false);
  const [passwordError, setPasswordError] = useState<string | null>(null);
  const [passwordSuccess, setPasswordSuccess] = useState(false);

  useEffect(() => {
    if (user) {
      setDisplayName(user.display_name || '');
      setBio(user.bio || '');
      setStatusText(user.status_text || '');
      setAccentColor(user.accent_color || '#fe8019');
    }
    checkSubscription();
  }, [user, checkSubscription]);

  if (!user) {
    navigate('/login');
    return null;
  }

  const handleSave = async (e: React.FormEvent) => {
    e.preventDefault();
    clearError();
    setSaved(false);

    try {
      await updateProfile({
        display_name: displayName,
        bio,
        status_text: statusText,
        accent_color: accentColor,
      });
      setSaved(true);
      setTimeout(() => setSaved(false), 3000);
    } catch {
      // error is set in store
    }
  };

  const handleAvatarUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setUploading(true);
    setUploadError(null);

    try {
      const formData = new FormData();
      formData.append('file', file);

      const response = await fetch('/api/v1/upload', {
        method: 'POST',
        credentials: 'include',
        body: formData,
      });

      if (!response.ok) {
        const data = await response.json().catch(() => null);
        throw new Error(data?.message || data?.error || `Upload failed: ${response.status}`);
      }

      const uploadData = await response.json();
      await updateProfile({ avatar_url: uploadData.url });
    } catch (err) {
      setUploadError(err instanceof Error ? err.message : 'Upload failed');
    } finally {
      setUploading(false);
      if (fileInputRef.current) {
        fileInputRef.current.value = '';
      }
    }
  };

  const hexValid = /^#[0-9a-fA-F]{6}$/.test(accentColor);

  const handleChangePassword = async () => {
    setPasswordError(null);
    setPasswordSuccess(false);
    if (newPassword !== confirmNewPassword) {
      setPasswordError("new passwords do not match");
      return;
    }
    if (newPassword.length < 8) {
      setPasswordError("password must be at least 8 characters");
      return;
    }
    setPasswordLoading(true);
    try {
      await changePassword(currentPassword, newPassword);
      setPasswordSuccess(true);
      setCurrentPassword('');
      setNewPassword('');
      setConfirmNewPassword('');
      setTimeout(() => setPasswordSuccess(false), 3000);
    } catch {
      // error is set in store
    } finally {
      setPasswordLoading(false);
    }
  };

  return (
    <div className="h-full w-full bg-gb-bg p-4 md:p-8 overflow-y-auto">
      <div className="max-w-2xl mx-auto">
        {/* Box-drawn frame */}
        <div className="border border-gb-bg-t p-6">
          {/* Header */}
          <pre className="text-gb-orange font-mono text-center mb-6">
            {'┌──────────────────────────────────┐\n'}
            {'│   === PROFILE SETTINGS ===       │\n'}
            {'└──────────────────────────────────┘'}
          </pre>

          <form onSubmit={handleSave} className="space-y-5">
            {/* Avatar Section */}
            <div className="border border-gb-bg-t p-4">
              <label className="block text-gb-fg-f mb-2 font-mono text-sm">
                AVATAR:
              </label>
              <div className="flex items-center gap-4">
                <div
                  className="w-16 h-16 rounded border-2 flex items-center justify-center overflow-hidden shrink-0"
                  style={{ borderColor: hexValid ? accentColor : '#504945' }}
                >
                  {user.avatar ? (
                    <img
                      src={user.avatar}
                      alt="avatar"
                      className="w-full h-full object-cover"
                    />
                  ) : (
                    <span className="text-gb-fg-f text-2xl font-mono">
                      {user.username.charAt(0).toUpperCase()}
                    </span>
                  )}
                </div>
                <div className="flex flex-col gap-2">
                  <span className="text-gb-fg-s text-sm font-mono truncate max-w-xs">
                    {user.avatar || 'no avatar set'}
                  </span>
                  <div className="flex items-center gap-2">
                    <button
                      type="button"
                      onClick={() => fileInputRef.current?.click()}
                      className="terminal-button text-xs"
                      disabled={uploading}
                    >
                      {uploading ? '[UPLOADING...]' : '[UPLOAD NEW]'}
                    </button>
                    <input
                      ref={fileInputRef}
                      type="file"
                      accept="image/*"
                      onChange={handleAvatarUpload}
                      className="hidden"
                    />
                  </div>
                  {uploadError && (
                    <p className="text-gb-red text-xs font-mono">ERR: {uploadError}</p>
                  )}
                </div>
              </div>
            </div>

            {/* Display Name */}
            <div>
              <label className="block text-gb-fg-f mb-1 font-mono text-sm">
                DISPLAY_NAME:
              </label>
              <input
                type="text"
                value={displayName}
                onChange={(e) => setDisplayName(e.target.value.slice(0, 32))}
                maxLength={32}
                className="terminal-input w-full"
                placeholder="your display name"
              />
              <span className="text-gb-fg-f text-xs font-mono mt-1 block">
                {displayName.length}/32
              </span>
            </div>

            {/* Bio */}
            <div>
              <label className="block text-gb-fg-f mb-1 font-mono text-sm">
                BIO:
              </label>
              <textarea
                value={bio}
                onChange={(e) => setBio(e.target.value.slice(0, 250))}
                maxLength={250}
                rows={4}
                className="terminal-input w-full resize-none"
                placeholder="tell the world about yourself..."
              />
              <span className="text-gb-fg-f text-xs font-mono mt-1 block">
                {bio.length}/250
              </span>
            </div>

            {/* Status Text */}
            <div>
              <label className="block text-gb-fg-f mb-1 font-mono text-sm">
                STATUS_TEXT:
              </label>
              <input
                type="text"
                value={statusText}
                onChange={(e) => setStatusText(e.target.value.slice(0, 128))}
                maxLength={128}
                className="terminal-input w-full"
                placeholder="what are you up to?"
              />
              <span className="text-gb-fg-f text-xs font-mono mt-1 block">
                {statusText.length}/128
              </span>
            </div>

            {/* Accent Color */}
            <div>
              <label className="block text-gb-fg-f mb-1 font-mono text-sm">
                ACCENT_COLOR:
              </label>
              <div className="flex items-center gap-3">
                <input
                  type="text"
                  value={accentColor}
                  onChange={(e) => {
                    let val = e.target.value;
                    if (!val.startsWith('#')) val = '#' + val;
                    setAccentColor(val.slice(0, 7));
                  }}
                  maxLength={7}
                  className="terminal-input w-32"
                  placeholder="#fe8019"
                />
                <div
                  className="w-8 h-8 border border-gb-bg-t rounded-sm shrink-0"
                  style={{ backgroundColor: hexValid ? accentColor : '#504945' }}
                  title={hexValid ? accentColor : 'invalid hex'}
                />
                {!hexValid && accentColor.length > 0 && (
                  <span className="text-gb-red text-xs font-mono">
                    invalid hex
                  </span>
                )}
              </div>
            </div>

            {/* Change Password */}
            <div className="border border-gb-bg-t p-4">
              <label className="block text-gb-fg-f mb-2 font-mono text-sm">
                CHANGE PASSWORD:
              </label>
              <div className="space-y-3">
                <input
                  type="password"
                  value={currentPassword}
                  onChange={(e) => setCurrentPassword(e.target.value)}
                  className="terminal-input w-full"
                  placeholder="current password"
                  autoComplete="current-password"
                />
                <input
                  type="password"
                  value={newPassword}
                  onChange={(e) => setNewPassword(e.target.value)}
                  className="terminal-input w-full"
                  placeholder="new password (min 8 chars)"
                  autoComplete="new-password"
                />
                <input
                  type="password"
                  value={confirmNewPassword}
                  onChange={(e) => setConfirmNewPassword(e.target.value)}
                  className="terminal-input w-full"
                  placeholder="confirm new password"
                  autoComplete="new-password"
                />
                {passwordError && (
                  <p className="text-gb-red text-xs font-mono">ERR: {passwordError}</p>
                )}
                {passwordSuccess && (
                  <p className="text-gb-green text-xs font-mono">[password changed!]</p>
                )}
                <button
                  type="button"
                  onClick={handleChangePassword}
                  disabled={passwordLoading || !currentPassword || newPassword.length < 8 || newPassword !== confirmNewPassword}
                  className="terminal-button text-xs"
                >
                  {passwordLoading ? '[CHANGING...]' : '[CHANGE PASSWORD]'}
                </button>
              </div>
            </div>

            {/* Push Notifications */}
            {isSupported && (
              <div className="border border-gb-bg-t p-4">
                <label className="block text-gb-fg-f mb-2 font-mono text-sm">
                  NOTIFICATIONS:
                </label>
                <div className="flex flex-col gap-3">
                  <div className="flex items-center gap-3">
                    <button
                      type="button"
                      onClick={async () => {
                        if (Notification.permission !== 'granted') {
                          await Notification.requestPermission();
                          // Force a re-render to update the permission status
                          setDisplayName(displayName + ' '); setTimeout(() => setDisplayName(displayName), 0);
                        }
                      }}
                      className={`terminal-button text-xs ${Notification.permission === 'granted' ? 'border-gb-green text-gb-green' : 'border-gb-orange text-gb-orange'}`}
                    >
                      {Notification.permission === 'granted' ? '[DESKTOP GRANTED]' : '[ENABLE DESKTOP]'}
                    </button>
                    <span className="text-gb-fg-f text-xs font-mono">
                      {Notification.permission === 'granted' ? '● allowed' : '○ not allowed'}
                    </span>
                  </div>
                  <div className="flex items-center gap-3">
                    <button
                      type="button"
                      onClick={isSubscribed ? unsubscribe : subscribe}
                      className={`terminal-button text-xs ${isSubscribed ? 'border-gb-green text-gb-green' : 'border-gb-orange text-gb-orange'}`}
                    >
                      {isSubscribed ? '[DISABLE PUSH]' : '[ENABLE PUSH]'}
                    </button>
                    <span className="text-gb-fg-f text-xs font-mono">
                      {isSubscribed ? '● subscribed' : '○ not subscribed'}
                    </span>
                  </div>
                </div>
                <p className="text-gb-fg-f text-xs font-mono mt-2">
                  Enable Desktop to get notifications while the app is running in the background. Enable Push to get notifications when the app is fully closed.
                </p>
              </div>
            )}

            {/* Passkey Registration */}
            <div className="border border-gb-bg-t p-4">
              <label className="block text-gb-fg-f mb-2 font-mono text-sm">
                PASSKEYS:
              </label>
              <button
                type="button"
                onClick={async () => {
                  try {
                    const resp = await fetch('/api/v1/auth/webauthn/register/begin', { method: 'POST', credentials: 'include' });
                    if (!resp.ok) throw new Error('Passkey registration not available');
                    const options = await resp.json();
                    
                    const credential = await navigator.credentials.create({ publicKey: options });
                    if (!credential) return;
                    
                    const finishResp = await fetch('/api/v1/auth/webauthn/register/finish', {
                      method: 'POST',
                      credentials: 'include',
                      headers: { 'Content-Type': 'application/json' },
                      body: JSON.stringify(credential),
                    });
                    
                    if (finishResp.ok) {
                      alert('Passkey registered successfully!');
                    }
                  } catch (err) {
                    console.error('Passkey registration failed:', err);
                    alert('Passkey registration not yet available on this server.');
                  }
                }}
                className="terminal-button text-xs border-gb-aqua text-gb-aqua"
              >
                [REGISTER PASSKEY]
              </button>
              <p className="text-gb-fg-f text-xs font-mono mt-2">
                Use biometrics or security key for passwordless login.
              </p>
            </div>

            {/* Errors & Success */}
            {error && (
              <p className="text-gb-red text-sm font-mono">ERR: {error}</p>
            )}
            {saved && (
              <p className="text-gb-green text-sm font-mono animate-pulse">
                [saved!]
              </p>
            )}

            {/* Save Button */}
            <div className="flex items-center gap-3 pt-2">
              <button
                type="submit"
                className="terminal-button"
                disabled={isLoading || !hexValid}
              >
                {isLoading ? '[SAVING...]' : '[SAVE]'}
              </button>
              <Link
                to="/"
                className="text-gb-fg-f hover:text-gb-aqua font-mono text-sm"
              >
                [CANCEL]
              </Link>
            </div>
          </form>

          {/* Footer info */}
          <div className="mt-6 pt-4 border-t border-gb-bg-t">
            <p className="text-gb-fg-f text-xs font-mono">
              USER: {user.username} | ID: {user.id.slice(0, 8)}... | JOINED: {new Date(user.created_at).toLocaleDateString()}
            </p>
          </div>
        </div>
      </div>
    </div>
  );
}
