import React, { useState, useEffect, useMemo } from 'react';
import { MapPin, Plus, Edit, Trash2, Star } from 'lucide-react';
import { api } from '@/lib/api/client';
import { toast } from 'sonner';
import SEOHead from '@/components/SEOHead';
import { DynamicCheckoutField } from '@/components/DynamicCheckoutField';

interface Address {
  id: number;
  label: string;
  type: 'billing' | 'shipping' | 'both';
  first_name: string;
  last_name: string;
  company?: string;
  address_1: string;
  address_2?: string;
  city: string;
  state: string;
  postcode: string;
  country: string;
  email?: string;
  phone?: string;
  is_default: boolean;
  // Custom fields
  [key: string]: any;
}

interface CheckoutField {
  key: string;
  fieldset: 'billing' | 'shipping' | 'account' | 'order';
  type: string;
  label: string;
  placeholder?: string;
  required: boolean;
  hidden: boolean;
  class?: string[];
  priority: number;
  options?: Record<string, string> | null;
  custom: boolean;
  autocomplete?: string;
  validate?: string[];
  input_class?: string[];
  custom_attributes?: Record<string, string>;
  default?: string;
  search_endpoint?: string | null;
  search_param?: string;
  min_chars?: number;
}

interface CountryOption {
  value: string;
  label: string;
}

export default function Addresses() {
  const [addresses, setAddresses] = useState<Address[]>([]);
  const [loading, setLoading] = useState(true);
  const [showModal, setShowModal] = useState(false);
  const [editingAddress, setEditingAddress] = useState<Address | null>(null);
  const [formData, setFormData] = useState<Record<string, any>>({
    label: '',
    type: 'both',
    is_default: false,
  });

  // Checkout fields from API
  const [checkoutFields, setCheckoutFields] = useState<CheckoutField[]>([]);
  const [countryOptions, setCountryOptions] = useState<CountryOption[]>([]);
  const [stateOptions, setStateOptions] = useState<CountryOption[]>([]);
  const [loadingFields, setLoadingFields] = useState(true);

  // Fetch checkout fields and countries
  useEffect(() => {
    const loadFieldsAndCountries = async () => {
      try {
        // Fetch checkout fields (POST method required by API)
        const fieldsResponse = await api.post<{ fields: CheckoutField[] }>('/checkout/fields', {});
        setCheckoutFields(fieldsResponse.fields || []);

        // Fetch countries
        const countriesResponse = await api.get<{ countries: Record<string, string> }>('/countries');
        if (countriesResponse.countries) {
          const options = Object.entries(countriesResponse.countries).map(([code, name]) => ({
            value: code,
            label: String(name),
          }));
          setCountryOptions(options);
        }
      } catch (error) {
        console.error('Failed to load checkout fields:', error);
      } finally {
        setLoadingFields(false);
      }
    };
    loadFieldsAndCountries();
  }, []);

  // Listen for field label events from DynamicCheckoutField (searchable_select)
  // This captures the human-readable label alongside the ID value
  useEffect(() => {
    const handleFieldLabel = (event: CustomEvent<{ key: string; value: string }>) => {
      const { key, value } = event.detail;
      setFormData(prev => ({
        ...prev,
        [key]: value,
      }));
    };

    document.addEventListener('woonoow:field_label', handleFieldLabel as EventListener);
    return () => {
      document.removeEventListener('woonoow:field_label', handleFieldLabel as EventListener);
    };
  }, []);

  // Fetch states when country changes
  useEffect(() => {
    const country = formData.country || formData.billing_country || '';
    if (!country) {
      setStateOptions([]);
      return;
    }

    const loadStates = async () => {
      try {
        const response = await api.get<{ states: Record<string, string> }>(`/countries/${country}/states`);
        if (response.states) {
          const options = Object.entries(response.states).map(([code, name]) => ({
            value: code,
            label: String(name),
          }));
          setStateOptions(options);
        } else {
          setStateOptions([]);
        }
      } catch {
        setStateOptions([]);
      }
    };
    loadStates();
  }, [formData.country, formData.billing_country]);

  // Filter billing fields - API already returns them sorted by priority
  const billingFields = useMemo(() => {
    return checkoutFields
      .filter(f => f.fieldset === 'billing' && !f.hidden && f.type !== 'hidden');
  }, [checkoutFields]);

  useEffect(() => {
    loadAddresses();
  }, []);

  const loadAddresses = async () => {
    try {
      const response: any = await api.get('/account/addresses');

      // Handle different response structures
      let data: Address[] = [];

      if (Array.isArray(response)) {
        data = response;
      } else if (response && typeof response === 'object') {
        if (Array.isArray(response.data)) {
          data = response.data;
        } else if (Array.isArray(response.addresses)) {
          data = response.addresses;
        } else if (response.length !== undefined && typeof response === 'object') {
          data = Object.values(response).filter((item: any) => item && typeof item === 'object' && item.id) as Address[];
        }
      }
      setAddresses(data);
    } catch (error) {
      console.error('Load addresses error:', error);
      toast.error('Failed to load addresses');
      setAddresses([]);
    } finally {
      setLoading(false);
    }
  };

  // Helper to get field value - handles both prefixed and non-prefixed keys
  const getFieldValue = (key: string): string => {
    // Try exact key first
    if (formData[key] !== undefined) return String(formData[key] || '');

    // Try without prefix
    const unprefixed = key.replace(/^billing_/, '');
    if (formData[unprefixed] !== undefined) return String(formData[unprefixed] || '');

    return '';
  };

  // Helper to set field value - stores both prefixed and unprefixed for compatibility
  const setFieldValue = (key: string, value: string) => {
    const unprefixed = key.replace(/^billing_/, '');
    setFormData(prev => ({
      ...prev,
      [key]: value,
      [unprefixed]: value,
    }));
  };

  const handleAdd = () => {
    setEditingAddress(null);
    // Initialize with defaults from API fields
    const defaults: Record<string, any> = {
      label: '',
      type: 'both',
      is_default: false,
    };
    billingFields.forEach(field => {
      if (field.default) {
        const unprefixed = field.key.replace(/^billing_/, '');
        defaults[field.key] = field.default;
        defaults[unprefixed] = field.default;
      }
    });
    setFormData(defaults);
    setShowModal(true);
  };

  const handleEdit = (address: Address) => {
    setEditingAddress(address);
    // Map address fields to formData with both prefixed and unprefixed keys
    const data: Record<string, any> = { ...address };
    // Add billing_ prefixed versions
    Object.entries(address).forEach(([key, value]) => {
      data[`billing_${key}`] = value;
    });
    setFormData(data);
    setShowModal(true);
  };

  const handleSave = async () => {
    try {
      // Prepare payload with unprefixed keys
      const payload: Record<string, any> = {
        label: formData.label,
        type: formData.type,
        is_default: formData.is_default,
      };

      // Add all fields (unprefixed)
      billingFields.forEach(field => {
        const unprefixed = field.key.replace(/^billing_/, '');
        payload[unprefixed] = getFieldValue(field.key);

        // Also include _label fields if they exist (for searchable_select fields)
        const labelKey = field.key + '_label';
        if (formData[labelKey]) {
          const unprefixedLabel = unprefixed + '_label';
          payload[unprefixedLabel] = formData[labelKey];
        }
      });

      if (editingAddress) {
        await api.put(`/account/addresses/${editingAddress.id}`, payload);
        toast.success('Address updated successfully');
      } else {
        await api.post('/account/addresses', payload);
        toast.success('Address added successfully');
      }
      setShowModal(false);
      loadAddresses();
    } catch (error) {
      console.error('Save address error:', error);
      toast.error('Failed to save address');
    }
  };

  const handleDelete = async (id: number) => {
    if (!confirm('Are you sure you want to delete this address?')) return;

    try {
      await api.delete(`/account/addresses/${id}`);
      toast.success('Address deleted successfully');
      loadAddresses();
    } catch (error) {
      console.error('Delete address error:', error);
      toast.error('Failed to delete address');
    }
  };

  const handleSetDefault = async (id: number) => {
    try {
      await api.post(`/account/addresses/${id}/set-default`, {});
      toast.success('Default address updated');
      loadAddresses();
    } catch (error) {
      console.error('Set default error:', error);
      toast.error('Failed to set default address');
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center py-12">
        <div className="text-gray-600">Loading addresses...</div>
      </div>
    );
  }

  return (
    <div>
      <SEOHead title="Addresses" description="Manage your shipping and billing addresses" />
      <div className="flex items-center justify-between mb-6">
        <h1 className="text-2xl font-bold">Addresses</h1>
        <button
          onClick={handleAdd}
          className="font-[inherit] inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors"
        >
          <Plus className="w-4 h-4" />
          Add Address
        </button>
      </div>

      {addresses.length === 0 ? (
        <div className="text-center py-12 border rounded-lg">
          <MapPin className="w-12 h-12 text-gray-300 mx-auto mb-2" />
          <p className="text-gray-600 mb-4">No addresses saved yet</p>
          <button
            onClick={handleAdd}
            className="font-[inherit] inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors"
          >
            <Plus className="w-4 h-4" />
            Add Your First Address
          </button>
        </div>
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {addresses.map((address) => (
            <div key={address.id} className="border rounded-lg p-6 relative">
              {address.is_default && (
                <div className="absolute top-4 right-4">
                  <Star className="w-5 h-5 text-yellow-500 fill-yellow-500" />
                </div>
              )}

              <div className="mb-4">
                <h3 className="font-semibold text-lg">{address.label}</h3>
                <span className="text-xs text-gray-500 uppercase">
                  {address.type === 'both' ? 'Billing & Shipping' : address.type}
                </span>
              </div>

              <div className="text-sm text-gray-700 space-y-1 mb-4">
                <p className="font-medium">{address.first_name} {address.last_name}</p>
                {address.company && <p>{address.company}</p>}
                <p>{address.address_1}</p>
                {address.address_2 && <p>{address.address_2}</p>}
                <p>{address.city}, {address.state} {address.postcode}</p>
                <p>{address.country}</p>
                {address.phone && <p className="pt-2">Phone: {address.phone}</p>}
                {address.email && <p>Email: {address.email}</p>}
              </div>

              <div className="flex items-center gap-2">
                <button
                  onClick={() => handleEdit(address)}
                  className="font-[inherit] flex items-center gap-1 text-sm text-primary hover:underline"
                >
                  <Edit className="w-4 h-4" />
                  Edit
                </button>
                <button
                  onClick={() => handleDelete(address.id)}
                  className="font-[inherit] flex items-center gap-1 text-sm text-red-600 hover:underline"
                >
                  <Trash2 className="w-4 h-4" />
                  Delete
                </button>
                {!address.is_default && (
                  <button
                    onClick={() => handleSetDefault(address.id)}
                    className="font-[inherit] flex items-center gap-1 text-sm text-gray-600 hover:underline ml-auto"
                  >
                    <Star className="w-4 h-4" />
                    Set Default
                  </button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Address Modal */}
      {showModal && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
          <div className="bg-white rounded-lg max-w-2xl w-full max-h-[90vh] overflow-y-auto">
            <div className="p-6">
              <h2 className="text-xl font-bold mb-4">
                {editingAddress ? 'Edit Address' : 'Add New Address'}
              </h2>

              {loadingFields ? (
                <div className="py-8 text-center text-gray-500">Loading form fields...</div>
              ) : (
                <div className="space-y-4">
                  {/* Label field - always shown */}
                  <div>
                    <label className="block text-sm font-medium mb-1">Label *</label>
                    <input
                      type="text"
                      value={formData.label || ''}
                      onChange={(e) => setFormData({ ...formData, label: e.target.value })}
                      placeholder="e.g., Home, Office, Parents"
                      className="w-full px-3 py-2 border !rounded-lg"
                    />
                  </div>

                  {/* Address Type - always shown */}
                  <div>
                    <label className="block text-sm font-medium mb-1">Address Type *</label>
                    <select
                      value={formData.type || 'both'}
                      onChange={(e) => setFormData({ ...formData, type: e.target.value as Address['type'] })}
                      className="w-full px-3 py-2 border rounded-lg"
                    >
                      <option value="both">Billing & Shipping</option>
                      <option value="billing">Billing Only</option>
                      <option value="shipping">Shipping Only</option>
                    </select>
                  </div>

                  {/* Dynamic fields from checkout API - DynamicCheckoutField renders its own labels */}
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    {billingFields.map((field) => (
                      <DynamicCheckoutField
                        key={field.key}
                        field={field}
                        value={getFieldValue(field.key)}
                        onChange={(v) => setFieldValue(field.key, v)}
                        countryOptions={countryOptions}
                        stateOptions={stateOptions}
                      />
                    ))}
                  </div>

                  {/* Set as default checkbox */}
                  <div className="flex items-center gap-2 pt-2">
                    <input
                      type="checkbox"
                      id="is_default"
                      checked={formData.is_default || false}
                      onChange={(e) => setFormData({ ...formData, is_default: e.target.checked })}
                      className="w-4 h-4"
                    />
                    <label htmlFor="is_default" className="text-sm">Set as default address</label>
                  </div>
                </div>
              )}

              <div className="flex gap-3 mt-6">
                <button
                  onClick={handleSave}
                  disabled={loadingFields}
                  className="font-[inherit] flex-1 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors disabled:opacity-50"
                >
                  Save Address
                </button>
                <button
                  onClick={() => setShowModal(false)}
                  className="font-[inherit] px-4 py-2 border rounded-lg hover:bg-gray-50 transition-colors"
                >
                  Cancel
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
