import React, { useState, useEffect } from 'react';
import { usePersonalData, useCvStore, useTemplateId } from '../store/cvStore';
import { templatesMap } from '../templates/registry';
import { normalizeUrl } from '../schema/cvSchema';

const PersonalEditor: React.FC = () => {
  const personalData = usePersonalData();
  const { updatePersonal } = useCvStore();
  const templateId = useTemplateId();
  const supportsPhoto = !!templatesMap[templateId]?.supportsPhoto;
  const [formData, setFormData] = useState(personalData);
  const [errors, setErrors] = useState<Record<string, string>>({});

  useEffect(() => {
    setFormData(personalData);
  }, [personalData]);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
    
    // Clear error when user starts typing
    if (errors[name]) {
      setErrors(prev => ({ ...prev, [name]: '' }));
    }
  };

  const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    
    // Validate on blur
    if (name === 'firstName' && !value.trim()) {
      setErrors(prev => ({ ...prev, firstName: 'First name is required' }));
    } else if (name === 'lastName' && !value.trim()) {
      setErrors(prev => ({ ...prev, lastName: 'Last name is required' }));
    } else if (name === 'email') {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!value.trim()) {
        setErrors(prev => ({ ...prev, email: 'Email is required' }));
      } else if (!emailRegex.test(value)) {
        setErrors(prev => ({ ...prev, email: 'Invalid email format' }));
      }
    } else if (name === 'photoUrl' && value.trim()) {
      // Basic URL normalization and validation
      const normalized = normalizeUrl(value.trim());
      if (!/^https?:\/\//i.test(normalized)) {
        setErrors(prev => ({ ...prev, photoUrl: 'URL must start with http:// or https://' }));
      } else {
        setFormData(prev => ({ ...prev, photoUrl: normalized }));
      }
    }
    
    // Update store on blur if no errors
    if (!Object.values(errors).some(error => error)) {
      updatePersonal(formData);
    }
  };

  const handleAddLink = () => {
    const newLinks = [...formData.links, { id: Math.random().toString(36).substring(2, 9), label: '', url: '' }];
    setFormData(prev => ({ ...prev, links: newLinks }));
  };

  const handleLinkChange = (id: string, field: 'label' | 'url', value: string) => {
    const updatedLinks = formData.links.map(link => 
      link.id === id ? { ...link, [field]: value } : link
    );
    setFormData(prev => ({ ...prev, links: updatedLinks }));
    
    // Clear link errors
    if (errors[`link-${id}-${field}`]) {
      setErrors(prev => ({ ...prev, [`link-${id}-${field}`]: '' }));
    }
  };

  const handleLinkBlur = (id: string, field: 'label' | 'url', value: string) => {
    let hasError = false;
    
    if (field === 'url' && value) {
      try {
        // Normalize and validate URL
        const normalizedUrl = normalizeUrl(value);
        const updatedLinks = formData.links.map(link => 
          link.id === id ? { ...link, url: normalizedUrl } : link
        );
        setFormData(prev => ({ ...prev, links: updatedLinks }));
      } catch {
        setErrors(prev => ({ ...prev, [`link-${id}-url`]: 'Invalid URL format' }));
        hasError = true;
      }
    }
    
    if (!hasError) {
      updatePersonal(formData);
    }
  };

  const handleRemoveLink = (id: string) => {
    const updatedLinks = formData.links.filter(link => link.id !== id);
    const updatedFormData = { ...formData, links: updatedLinks };
    setFormData(updatedFormData);
    updatePersonal(updatedFormData);
  };

  // Extras: Headline (extras[0]) and Reference lines (extras[1..])
  const handleHeadlineChange = (value: string) => {
    const extras = Array.isArray(formData.extras) ? [...formData.extras] : [];
    extras[0] = value;
    const updatedFormData = { ...formData, extras };
    setFormData(updatedFormData);
  };

  const handleReferenceChange = (index: number, value: string) => {
    const extras = Array.isArray(formData.extras) ? [...formData.extras] : [];
    extras[index] = value;
    const updatedFormData = { ...formData, extras };
    setFormData(updatedFormData);
  };

  const handleAddReference = () => {
    const extras = Array.isArray(formData.extras) ? [...formData.extras] : [];
    extras.push("");
    const updatedFormData = { ...formData, extras };
    setFormData(updatedFormData);
  };

  const handleRemoveReference = (index: number) => {
    const extras = Array.isArray(formData.extras) ? [...formData.extras] : [];
    if (index >= 0 && index < extras.length) {
      extras.splice(index, 1);
    }
    const updatedFormData = { ...formData, extras };
    setFormData(updatedFormData);
    updatePersonal(updatedFormData);
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    
    // Validate all fields
    const newErrors: Record<string, string> = {};
    if (!formData.firstName.trim()) newErrors.firstName = 'First name is required';
    if (!formData.lastName.trim()) newErrors.lastName = 'Last name is required';
    
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!formData.email.trim()) {
      newErrors.email = 'Email is required';
    } else if (!emailRegex.test(formData.email)) {
      newErrors.email = 'Invalid email format';
    }
    
    // Validate links
    formData.links.forEach(link => {
      if (link.url && !link.url.startsWith('http')) {
        newErrors[`link-${link.id}-url`] = 'URL must start with http:// or https://';
      }
    });
    
    setErrors(newErrors);
    
    // Update store if no errors
    if (Object.keys(newErrors).length === 0) {
      updatePersonal(formData);
      return true;
    }
    
    return false;
  };

  return (
    <div className="max-w-2xl mx-auto p-6 bg-white rounded-lg shadow-sm">
      <h2 className="text-2xl font-bold mb-6">Personal Information</h2>
      
      <form onSubmit={handleSubmit} className="space-y-6">
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {/* First Name */}
          <div>
            <label htmlFor="firstName" className="block text-sm font-medium text-gray-700 mb-1">
              First Name *
            </label>
            <input
              type="text"
              id="firstName"
              name="firstName"
              value={formData.firstName}
              onChange={handleChange}
              onBlur={handleBlur}
              className={`w-full px-3 py-2 border rounded-md ${errors.firstName ? 'border-red-500' : 'border-gray-300'}`}
              aria-describedby={errors.firstName ? "firstName-error" : undefined}
            />
            {errors.firstName && (
              <p id="firstName-error" className="mt-1 text-sm text-red-600">
                {errors.firstName}
              </p>
            )}
          </div>
          
          {/* Last Name */}
          <div>
            <label htmlFor="lastName" className="block text-sm font-medium text-gray-700 mb-1">
              Last Name *
            </label>
            <input
              type="text"
              id="lastName"
              name="lastName"
              value={formData.lastName}
              onChange={handleChange}
              onBlur={handleBlur}
              className={`w-full px-3 py-2 border rounded-md ${errors.lastName ? 'border-red-500' : 'border-gray-300'}`}
              aria-describedby={errors.lastName ? "lastName-error" : undefined}
            />
            {errors.lastName && (
              <p id="lastName-error" className="mt-1 text-sm text-red-600">
                {errors.lastName}
              </p>
            )}
          </div>
          
          {/* Email */}
          <div>
            <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
              Email *
            </label>
            <input
              type="email"
              id="email"
              name="email"
              value={formData.email}
              onChange={handleChange}
              onBlur={handleBlur}
              className={`w-full px-3 py-2 border rounded-md ${errors.email ? 'border-red-500' : 'border-gray-300'}`}
              aria-describedby={errors.email ? "email-error" : undefined}
            />
            {errors.email && (
              <p id="email-error" className="mt-1 text-sm text-red-600">
                {errors.email}
              </p>
            )}
          </div>
          
        {/* Phone */}
        <div>
          <label htmlFor="phone" className="block text-sm font-medium text-gray-700 mb-1">
            Phone
          </label>
          <input
            type="tel"
            id="phone"
            name="phone"
            value={formData.phone || ''}
            onChange={handleChange}
            onBlur={handleBlur}
            className="w-full px-3 py-2 border border-gray-300 rounded-md"
          />
        </div>

        {/* Photo URL (only for templates that support photos) */}
        {supportsPhoto && (
          <div>
            <label htmlFor="photoUrl" className="block text-sm font-medium text-gray-700 mb-1">
              Photo URL
            </label>
            <input
              type="url"
              id="photoUrl"
              name="photoUrl"
              placeholder="https://example.com/photo.jpg"
              value={formData.photoUrl || ''}
              onChange={handleChange}
              onBlur={handleBlur}
              className={`w-full px-3 py-2 border rounded-md ${errors.photoUrl ? 'border-red-500' : 'border-gray-300'}`}
              aria-describedby={errors.photoUrl ? 'photoUrl-error' : undefined}
            />
            {errors.photoUrl && (
              <p id="photoUrl-error" className="mt-1 text-sm text-red-600">{errors.photoUrl}</p>
            )}
          </div>
        )}
      </div>
        
        {/* Address Fields */}
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          <div>
            <label htmlFor="street" className="block text-sm font-medium text-gray-700 mb-1">
              Street Address
            </label>
            <input
              type="text"
              id="street"
              name="street"
              value={formData.street || ''}
              onChange={handleChange}
              onBlur={handleBlur}
              className="w-full px-3 py-2 border border-gray-300 rounded-md"
            />
          </div>
          
          <div>
            <label htmlFor="city" className="block text-sm font-medium text-gray-700 mb-1">
              City
            </label>
            <input
              type="text"
              id="city"
              name="city"
              value={formData.city || ''}
              onChange={handleChange}
              onBlur={handleBlur}
              className="w-full px-3 py-2 border border-gray-300 rounded-md"
            />
          </div>
          
          <div>
            <label htmlFor="country" className="block text-sm font-medium text-gray-700 mb-1">
              Country
            </label>
            <input
              type="text"
              id="country"
              name="country"
              value={formData.country || ''}
              onChange={handleChange}
              onBlur={handleBlur}
              className="w-full px-3 py-2 border border-gray-300 rounded-md"
            />
          </div>
          
          <div>
            <label htmlFor="postcode" className="block text-sm font-medium text-gray-700 mb-1">
              Postal Code
            </label>
            <input
              type="text"
              id="postcode"
              name="postcode"
              value={formData.postcode || ''}
              onChange={handleChange}
              onBlur={handleBlur}
              className="w-full px-3 py-2 border border-gray-300 rounded-md"
            />
          </div>
        </div>
        
        {/* Links Section */}
        <div className="mt-6">
          <div className="flex justify-between items-center mb-2">
            <h3 className="text-lg font-medium">Links</h3>
            <button
              type="button"
              onClick={handleAddLink}
              className="px-3 py-1 bg-blue-50 text-blue-600 rounded-md text-sm hover:bg-blue-100"
            >
              Add Link
            </button>
          </div>
          
          {formData.links.map((link) => (
            <div key={link.id} className="flex items-start space-x-2 mb-3">
              <div className="flex-1">
                <input
                  type="text"
                  placeholder="Label (e.g. LinkedIn)"
                  value={link.label}
                  onChange={(e) => handleLinkChange(link.id, 'label', e.target.value)}
                  onBlur={(e) => handleLinkBlur(link.id, 'label', e.target.value)}
                  className={`w-full px-3 py-2 border rounded-md ${
                    errors[`link-${link.id}-label`] ? 'border-red-500' : 'border-gray-300'
                  }`}
                />
                {errors[`link-${link.id}-label`] && (
                  <p className="mt-1 text-sm text-red-600">{errors[`link-${link.id}-label`]}</p>
                )}
              </div>
              
              <div className="flex-1">
                <input
                  type="text"
                  placeholder="URL (e.g. https://linkedin.com/in/...)"
                  value={link.url}
                  onChange={(e) => handleLinkChange(link.id, 'url', e.target.value)}
                  onBlur={(e) => handleLinkBlur(link.id, 'url', e.target.value)}
                  className={`w-full px-3 py-2 border rounded-md ${
                    errors[`link-${link.id}-url`] ? 'border-red-500' : 'border-gray-300'
                  }`}
                />
                {errors[`link-${link.id}-url`] && (
                  <p className="mt-1 text-sm text-red-600">{errors[`link-${link.id}-url`]}</p>
                )}
              </div>
              
              <button
                type="button"
                onClick={() => handleRemoveLink(link.id)}
                className="mt-2 text-red-500 hover:text-red-700"
                aria-label="Remove link"
              >
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                </svg>
              </button>
            </div>
          ))}
        </div>

        {/* Headline & Reference Section */}
        <div className="mt-6">
          <h3 className="text-lg font-medium mb-2">Headline & Reference</h3>
          {/* Headline */}
          <div className="mb-4">
            <label htmlFor="headline" className="block text-sm font-medium text-gray-700 mb-1">
              Headline (under your name)
            </label>
            <input
              type="text"
              id="headline"
              name="headline"
              placeholder="e.g., Marketing Manager"
              value={(formData.extras && formData.extras[0]) ? formData.extras[0] : ''}
              onChange={(e) => handleHeadlineChange(e.target.value)}
              onBlur={() => updatePersonal(formData)}
              className="w-full px-3 py-2 border border-gray-300 rounded-md"
            />
          </div>

          {/* Reference Lines */}
          <div className="flex justify-between items-center mb-2">
            <h4 className="text-sm font-medium">Reference Lines (left sidebar)</h4>
            <button
              type="button"
              onClick={handleAddReference}
              className="px-3 py-1 bg-blue-50 text-blue-600 rounded-md text-sm hover:bg-blue-100"
            >
              Add Reference Line
            </button>
          </div>
          {(formData.extras || []).slice(1).map((line, i) => (
            <div key={`ref-${i}`} className="flex items-start space-x-2 mb-3">
              <div className="flex-1">
                <input
                  type="text"
                  placeholder={`Reference line ${i + 1}`}
                  value={line}
                  onChange={(e) => handleReferenceChange(i + 1, e.target.value)}
                  onBlur={() => updatePersonal(formData)}
                  className="w-full px-3 py-2 border border-gray-300 rounded-md"
                />
              </div>
              <button
                type="button"
                onClick={() => handleRemoveReference(i + 1)}
                className="mt-2 text-red-500 hover:text-red-700"
                aria-label="Remove reference line"
              >
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                </svg>
              </button>
            </div>
          ))}
        </div>
      </form>
    </div>
  );
};

export default PersonalEditor;