'use client';

import { useEffect, useRef, useState } from 'react';
import { Save, X, Eye, EyeOff, Camera, User as UserIcon } from 'lucide-react';
import Input from '@/components/Input';
import Swal from 'sweetalert2';
import { api, BACKEND_URL } from '@/lib/api';

interface ProfileFormData {
  name: string;
  email: string;
  phone: string;
  password: string;
  confirmPassword: string;
}

// profilePic is stored on the backend as a relative path (e.g.
// "uploads/profilePics/123.png"); build a full URL for previewing it.
const buildPhotoUrl = (profilePic?: string | null): string => {
  if (!profilePic) return '';
  if (profilePic.startsWith('http')) return profilePic;
  return `${BACKEND_URL}/${profilePic.replace(/^\.?\//, '')}`;
};

export default function ProfileForm() {
  const [formData, setFormData] = useState<ProfileFormData>({
    name: '',
    email: '',
    phone: '',
    password: '',
    confirmPassword: '',
  });
  const [loading, setLoading] = useState(false);
  const [fetching, setFetching] = useState(true);
  const [errors, setErrors] = useState<{ [key: string]: string }>({});
  const [showPasswords, setShowPasswords] = useState({
    password: false,
    confirmPassword: false,
  });

  // Existing photo URL from the server + a locally-selected new file/preview.
  const [existingPhoto, setExistingPhoto] = useState('');
  const [photoFile, setPhotoFile] = useState<File | null>(null);
  const [photoPreview, setPhotoPreview] = useState('');
  const fileInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    const fetchProfile = async () => {
      try {
        const res = await api.get<any>('/auth/profile');
        const profile = res?.data || res;
        setFormData((prev) => ({
          ...prev,
          name: profile?.name || '',
          email: profile?.email || '',
          phone: profile?.phone || '',
        }));
        setExistingPhoto(buildPhotoUrl(profile?.profilePic));
      } catch (error: any) {
        Swal.fire('Error', error.message || 'Failed to load profile', 'error');
      } finally {
        setFetching(false);
      }
    };
    fetchProfile();
  }, []);

  const togglePasswordVisibility = (field: keyof typeof showPasswords) => {
    setShowPasswords((prev) => ({ ...prev, [field]: !prev[field] }));
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData((prev) => ({ ...prev, [name]: value }));
    if (errors[name]) {
      setErrors((prev) => {
        const newErrors = { ...prev };
        delete newErrors[name];
        return newErrors;
      });
    }
  };

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

    const allowedTypes = ['image/png', 'image/jpg', 'image/jpeg'];
    if (!allowedTypes.includes(file.type)) {
      Swal.fire('Error', 'Please select a PNG or JPG image', 'error');
      return;
    }
    if (file.size > 5 * 1024 * 1024) {
      Swal.fire('Error', 'Image must be smaller than 5MB', 'error');
      return;
    }

    setPhotoFile(file);
    setPhotoPreview(URL.createObjectURL(file));
  };

  const validateForm = () => {
    const newErrors: { [key: string]: string } = {};

    if (!formData.name.trim()) newErrors.name = 'Name is required';
    if (!formData.email.trim()) newErrors.email = 'Email is required';
    if (!formData.phone.trim()) newErrors.phone = 'Phone is required';

    // Password is optional, but if provided it must be valid and confirmed.
    if (formData.password) {
      if (formData.password.length < 6) {
        newErrors.password = 'Password must be at least 6 characters';
      }
      if (formData.password !== formData.confirmPassword) {
        newErrors.confirmPassword = 'Password and confirmation do not match';
      }
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (!validateForm()) return;

    setLoading(true);
    try {
      const payload = new FormData();
      payload.append('name', formData.name.trim());
      payload.append('email', formData.email.trim());
      payload.append('phone', formData.phone.trim());
      // Only send password when the user actually typed a new one.
      if (formData.password) {
        payload.append('password', formData.password);
      }
      if (photoFile) {
        payload.append('profilePic', photoFile);
      }

      const res = await api.patchUpload<any>('/auth/profile', payload);
      const updated = res?.data || res;

      // Reflect the saved photo and clear password fields.
      if (updated?.profilePic) {
        setExistingPhoto(buildPhotoUrl(updated.profilePic));
      }
      setPhotoFile(null);
      setPhotoPreview('');
      setFormData((prev) => ({ ...prev, password: '', confirmPassword: '' }));

      // Notify the navbar (and any other listeners) to reload the avatar.
      window.dispatchEvent(new Event('profile-updated'));

      Swal.fire('Success', 'Profile updated successfully!', 'success');
    } catch (error: any) {
      Swal.fire('Error', error.message || 'Failed to update profile', 'error');
    } finally {
      setLoading(false);
    }
  };

  const currentPhoto = photoPreview || existingPhoto;

  if (fetching) {
    return (
      <div className="bg-white p-8 rounded-2xl shadow-sm border border-gray-100 max-w-4xl mx-auto">
        <div className="flex justify-center py-16">
          <div className="animate-spin rounded-full h-10 w-10 border-b-2 border-[#dd3a3f]" />
        </div>
      </div>
    );
  }

  return (
    <div className="bg-white p-8 rounded-2xl shadow-sm border border-gray-100 max-w-4xl mx-auto">
      <h2 className="text-3xl font-bold text-gray-800 mb-8 border-b pb-4">My Profile</h2>
      <form onSubmit={handleSubmit}>
        {/* Profile photo */}
        <div className="flex flex-col items-center mb-8">
          <div className="relative">
            <div className="h-28 w-28 rounded-full overflow-hidden bg-gray-100 border-4 border-gray-100 flex items-center justify-center">
              {currentPhoto ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img src={currentPhoto} alt="Profile" className="h-full w-full object-cover" />
              ) : (
                <UserIcon className="w-12 h-12 text-gray-400" />
              )}
            </div>
            <button
              type="button"
              onClick={() => fileInputRef.current?.click()}
              className="absolute bottom-0 right-0 bg-[#dd3a3f] hover:bg-[#ad272b] text-white p-2 rounded-full shadow-md transition-colors"
              title="Change photo"
            >
              <Camera className="w-4 h-4" />
            </button>
          </div>
          <input
            ref={fileInputRef}
            type="file"
            accept="image/png,image/jpg,image/jpeg"
            className="hidden"
            onChange={handlePhotoChange}
          />
          <p className="text-xs text-gray-400 mt-3">PNG or JPG, up to 5MB</p>
        </div>

        <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
          <div>
            <Input
              label="Name"
              id="name"
              name="name"
              type="text"
              required
              value={formData.name}
              onChange={handleChange}
            />
            {errors.name && <p className="text-red-500 text-xs mt-1">{errors.name}</p>}
          </div>

          <div>
            <Input
              label="Email"
              id="email"
              name="email"
              type="email"
              required
              value={formData.email}
              onChange={handleChange}
            />
            {errors.email && <p className="text-red-500 text-xs mt-1">{errors.email}</p>}
          </div>

          <div>
            <Input
              label="Phone"
              id="phone"
              name="phone"
              type="text"
              required
              value={formData.phone}
              onChange={handleChange}
            />
            {errors.phone && <p className="text-red-500 text-xs mt-1">{errors.phone}</p>}
          </div>
        </div>

        <div className="mt-8 border-t pt-6">
          <h3 className="text-lg font-semibold text-gray-700 mb-1">Change Password</h3>
          <p className="text-sm text-gray-400 mb-4">
            Leave these blank to keep your current password.
          </p>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
            <div>
              <div className="relative">
                <Input
                  label="New Password"
                  id="password"
                  name="password"
                  type={showPasswords.password ? 'text' : 'password'}
                  autoComplete="new-password"
                  value={formData.password}
                  onChange={handleChange}
                />
                <button
                  type="button"
                  onClick={() => togglePasswordVisibility('password')}
                  className="absolute right-3 top-3 text-gray-500 hover:text-gray-700"
                >
                  {showPasswords.password ? <EyeOff size={20} /> : <Eye size={20} />}
                </button>
              </div>
              {errors.password && <p className="text-red-500 text-xs mt-1">{errors.password}</p>}
            </div>

            <div>
              <div className="relative">
                <Input
                  label="Confirm Password"
                  id="confirmPassword"
                  name="confirmPassword"
                  type={showPasswords.confirmPassword ? 'text' : 'password'}
                  autoComplete="new-password"
                  value={formData.confirmPassword}
                  onChange={handleChange}
                />
                <button
                  type="button"
                  onClick={() => togglePasswordVisibility('confirmPassword')}
                  className="absolute right-3 top-3 text-gray-500 hover:text-gray-700"
                >
                  {showPasswords.confirmPassword ? <EyeOff size={20} /> : <Eye size={20} />}
                </button>
              </div>
              {errors.confirmPassword && (
                <p className="text-red-500 text-xs mt-1">{errors.confirmPassword}</p>
              )}
            </div>
          </div>
        </div>

        <div className="flex justify-end space-x-4 mt-8">
          <button
            type="submit"
            disabled={loading}
            className="flex items-center px-6 py-3 bg-[#dd3a3f] text-white rounded-xl hover:bg-[#ad272b] transition-all duration-200 active:scale-95 shadow-md hover:shadow-lg disabled:opacity-50"
          >
            <Save className="w-4 h-4 mr-2" />
            {loading ? 'Saving...' : 'Save Changes'}
          </button>
        </div>
      </form>
    </div>
  );
}
