import React, { useState, useEffect, useRef } from 'react';
import * as apiClient from '../services/apiClient';
import { UserProfile, Achievement, UserAchievement } from '../types';
import { logger } from '../services/logger.client';
import { notifySuccess, notifyError } from '../services/notificationService';
import { AchievementsList } from '../components/AchievementsList';

const UserProfilePage: React.FC = () => {
  const [profile, setProfile] = useState<UserProfile | null>(null);
  const [achievements, setAchievements] = useState<(UserAchievement & Achievement)[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [isEditingName, setIsEditingName] = useState(false);
  const [editingName, setEditingName] = useState('');
  const [isUploading, setIsUploading] = useState(false);

  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    const fetchData = async () => {
      setIsLoading(true);
      try {
        // Fetch profile and achievements data in parallel
        const [profileRes, achievementsRes] = await Promise.all([
          apiClient.getAuthenticatedUserProfile(),
          apiClient.getUserAchievements(),
        ]);

        if (!profileRes.ok) throw new Error('Failed to fetch user profile.');
        if (!achievementsRes.ok) throw new Error('Failed to fetch user achievements.');

        const profileData: UserProfile = await profileRes.json();
        const achievementsData: (UserAchievement & Achievement)[] = await achievementsRes.json();

        setProfile(profileData);
        setEditingName(profileData.full_name || '');
        setAchievements(achievementsData);
      } catch (err) {
        const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';
        setError(errorMessage);
        logger.error({ err }, 'Error fetching user profile data:');
      } finally {
        setIsLoading(false);
      }
    };

    fetchData();
  }, []); // Empty dependency array means this runs once on component mount

  const handleSaveName = async () => {
    if (!profile) return;

    try {
      const response = await apiClient.updateUserProfile({ full_name: editingName });
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.message || 'Failed to update name.');
      }
      const updatedProfile = await response.json();
      setProfile(prevProfile => prevProfile ? { ...prevProfile, ...updatedProfile } : null);
      notifySuccess('Name updated successfully!');
      setIsEditingName(false);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';
      notifyError(errorMessage);
      logger.error({ err }, 'Error saving user name:');
    }
  };

  const handleAvatarClick = () => {
    // Programmatically click the hidden file input
    fileInputRef.current?.click();
  };

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

    setIsUploading(true);
    try {
      const response = await apiClient.uploadAvatar(file);
      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.message || 'Failed to upload avatar.');
      }
      const updatedProfile = await response.json();
      setProfile(prevProfile => prevProfile ? { ...prevProfile, ...updatedProfile } : null);
      notifySuccess('Avatar updated successfully!');
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';
      notifyError(errorMessage);
      logger.error({ err }, 'Error uploading avatar:');
    } finally {
      setIsUploading(false);
    }
  };

  if (isLoading) {
    return <div className="p-6 text-center">Loading profile...</div>;
  }

  if (error) {
    return <div className="p-6 text-center text-red-500">Error: {error}</div>;
  }

  if (!profile) {
    return <div className="p-6 text-center">Could not load user profile.</div>;
  }

  return (
    <div className="p-4 md:p-8 max-w-4xl mx-auto">
      {/* Profile Header */}
      <div className="flex items-center space-x-6 mb-8">
        <div className="relative group">
          <img
            src={profile.avatar_url || `https://api.dicebear.com/8.x/initials/svg?seed=${profile.full_name || profile.user.email}`}
            alt="User Avatar"
            className="w-24 h-24 rounded-full object-cover shadow-lg cursor-pointer transition-opacity group-hover:opacity-70"
            onClick={handleAvatarClick}
          />
          <div className="absolute inset-0 bg-black bg-opacity-50 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer" onClick={handleAvatarClick}>
            <span className="text-white text-sm font-semibold">Change</span>
          </div>
          {isUploading && <div data-testid="avatar-upload-spinner" className="absolute inset-0 bg-black bg-opacity-70 rounded-full flex items-center justify-center"><div className="w-8 h-8 border-4 border-t-transparent border-white rounded-full animate-spin"></div></div>}
        </div>
        <input
          type="file"
          ref={fileInputRef}
          onChange={handleFileChange}
          className="hidden"
          data-testid="avatar-file-input"
          accept="image/png, image/jpeg, image/gif"
        />
        <div>
          {isEditingName ? (
            <div className="flex items-center gap-2">
              <input
                type="text"
                value={editingName}
                onChange={(e) => setEditingName(e.target.value)}
                className="text-3xl font-bold p-1 border rounded dark:bg-gray-700 dark:border-gray-600"
                autoFocus
              />
              <button onClick={handleSaveName} className="bg-green-500 hover:bg-green-600 text-white font-bold py-1 px-3 rounded">Save</button>
              <button onClick={() => setIsEditingName(false)} className="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-1 px-3 rounded">Cancel</button>
            </div>
          ) : (
            <div className="flex items-center gap-4">
              <h1 className="text-3xl font-bold">{profile.full_name || 'User Profile'}</h1>
              <button onClick={() => setIsEditingName(true)} className="text-sm text-blue-500 hover:underline">Edit</button>
            </div>
          )}
          <p className="text-gray-500 dark:text-gray-400">{profile.user.email}</p>
          <div className="mt-2 bg-blue-100 text-blue-800 text-lg font-bold px-4 py-1 rounded-full inline-block">
            {profile.points} Points
          </div>
        </div>
      </div>

      {/* Achievements Section */}
      <AchievementsList achievements={achievements} />
    </div>
  );
};

export default UserProfilePage;