'use client';

import { useState, useRef, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { QuickLinks } from './components';
import DynamicSection from './components/DynamicSection';
import RepeatableSection, { RepeatableEntryData } from './components/RepeatableSection';
import { profileSectionsService, ProfileSection, AgentTypeSectionsResponse } from '@/services/profile-sections.service';
import { agentsService, AgentProfile, FieldValueInput } from '@/services/agents.service';
import { validateFieldValue } from '@/utils/validateFieldValue';
import { usersService } from '@/services/users.service';
import { MobileBackButton } from '@/components/layout/MobileBackButton';

export default function EditProfilePage() {
  const router = useRouter();
  const scrollContainerRef = useRef<HTMLDivElement>(null);

  // State for agent profile and dynamic sections
  const [agentProfile, setAgentProfile] = useState<AgentProfile | null>(null);
  const [sections, setSections] = useState<ProfileSection[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // Form data keyed by field slug
  const [formData, setFormData] = useState<Record<string, unknown>>({});
  // Repeatable sections data keyed by section slug
  const [repeatableData, setRepeatableData] = useState<Record<string, RepeatableEntryData[]>>({});
  const [formErrors, setFormErrors] = useState<Record<string, string>>({});
  const [repeatableErrors, setRepeatableErrors] = useState<Record<string, Record<string, Record<string, string>>>>({});
  const [isSaving, setIsSaving] = useState(false);

  // Fetch agent profile and sections on mount
  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        setError(null);

        // First, fetch the agent's profile to get their agentTypeId
        const profile = await agentsService.getMyProfile();
        setAgentProfile(profile);

        // Block editing when verification is under review
        if (profile.verificationStatus === 'PENDING_REVIEW') {
          router.push('/agent/dashboard');
          return;
        }

        if (!profile.agentTypeId) {
          setError('Your profile does not have an agent type assigned. Please contact support.');
          setLoading(false);
          return;
        }

        // Now fetch the sections for this agent type
        const response: AgentTypeSectionsResponse = await profileSectionsService.getSectionsForAgentType(profile.agentTypeId);

        // Sort sections by effectiveSortOrder
        const sortedSections = [...response.sections].sort(
          (a, b) => (a.effectiveSortOrder || a.sortOrder) - (b.effectiveSortOrder || b.sortOrder)
        );

        setSections(sortedSections);

        // Debug: Log all sections and their isRepeatable status
        console.log('All sections:', sortedSections.map(s => ({ slug: s.slug, name: s.name, isRepeatable: s.isRepeatable })));

        // Initialize form data with existing profile data + default values from fields
        const initialData: Record<string, unknown> = {};

        // Pre-fill with existing profile data
        if (profile.firstName) initialData['first-name'] = profile.firstName;
        if (profile.lastName) initialData['last-name'] = profile.lastName;
        if (profile.email) initialData['email'] = profile.email;
        // Note: phone is populated from dynamic field values (slug: phone_number)
        // Don't pre-populate 'phone' here as it creates a stale shadow entry
        // that conflicts with the dynamic field during save
        if (profile.bio) initialData['bio'] = profile.bio;
        if (profile.licenseNumber) initialData['license-number'] = profile.licenseNumber;
        if (profile.experience) initialData['experience'] = profile.experience;
        if (profile.specializations?.length) initialData['specializations'] = profile.specializations;
        if (profile.languages?.length) initialData['languages'] = profile.languages;
        if (profile.serviceAreas?.length) initialData['service-areas'] = profile.serviceAreas;

        // Then apply field default values where no existing data
        sortedSections.forEach(section => {
          const sectionFields = Array.isArray(section.fields) ? section.fields : [];
          sectionFields.forEach(field => {
            if (!field || !field.slug) return; // Skip malformed fields
            if (field.defaultValue && initialData[field.slug] === undefined) {
              // Parse default value based on field type
              switch (field.fieldType) {
                case 'CHECKBOX':
                  initialData[field.slug] = field.defaultValue === 'true';
                  break;
                case 'NUMBER':
                case 'RANGE':
                  initialData[field.slug] = parseFloat(field.defaultValue) || 0;
                  break;
                case 'CHECKBOX_GROUP':
                case 'MULTI_SELECT':
                case 'TAG_INPUT':
                  try {
                    initialData[field.slug] = JSON.parse(field.defaultValue);
                  } catch {
                    initialData[field.slug] = [];
                  }
                  break;
                default:
                  initialData[field.slug] = field.defaultValue;
              }
            }
          });
        });

        // Fetch existing field values from the API
        try {
          const fieldValuesResponse = await agentsService.getFieldValues();
          if (fieldValuesResponse.fieldValues) {
            // Build a lookup of current valid option values per enumerated-field slug
            const enumTypes = new Set(['CHECKBOX_GROUP', 'MULTI_SELECT', 'SELECT', 'RADIO']);
            const validOptionsBySlug = new Map<string, Set<string>>();
            sortedSections.forEach((section) => {
              const sectionFields = Array.isArray(section.fields) ? section.fields : [];
              sectionFields.forEach((field) => {
                if (!field?.slug || !enumTypes.has(field.fieldType)) return;
                const opts = Array.isArray(field.options) ? field.options : [];
                validOptionsBySlug.set(
                  field.slug,
                  new Set(opts.map((o: { value: string }) => String(o.value))),
                );
              });
            });

            fieldValuesResponse.fieldValues.forEach(fv => {
              if (fv.value === null || fv.value === undefined) return;
              let val: unknown = fv.value;
              // Strip orphan option values from stored arrays/strings so the form
              // never carries stale selections forward on the next save.
              const validValues = validOptionsBySlug.get(fv.fieldSlug);
              if (validValues) {
                if (Array.isArray(val)) {
                  val = (val as unknown[])
                    .filter((v) => validValues.has(String(v)))
                    .filter((v, i, arr) => arr.indexOf(v) === i);
                } else if (typeof val === 'string' && !validValues.has(val)) {
                  val = '';
                }
              }
              initialData[fv.fieldSlug] = val;
            });
          }
        } catch (fieldValueErr) {
          // If field values don't exist yet, that's OK - just use defaults
          console.log('No existing field values found, using defaults');
        }

        setFormData(initialData);

        // Initialize repeatable sections data
        const initialRepeatableData: Record<string, RepeatableEntryData[]> = {};
        sortedSections.forEach(section => {
          if (section.isRepeatable) {
            // Check if there's existing data for this section (stored as `${sectionSlug}_entries`)
            const entriesKey = `${section.slug}_entries`;
            const existingEntries = initialData[entriesKey];
            if (Array.isArray(existingEntries) && existingEntries.length > 0) {
              initialRepeatableData[section.slug] = existingEntries as RepeatableEntryData[];
            } else {
              // Initialize with one empty entry
              initialRepeatableData[section.slug] = [{}];
            }
          }
        });

        // Also check for any _entries fields that might not match a repeatable section
        // This handles cases where data was saved but section isn't marked as repeatable
        Object.keys(initialData).forEach(key => {
          if (key.endsWith('_entries') && Array.isArray(initialData[key])) {
            const sectionSlug = key.replace('_entries', '');
            if (!initialRepeatableData[sectionSlug]) {
              // Find the section by slug
              const section = sortedSections.find(s => s.slug === sectionSlug);
              if (section) {
                initialRepeatableData[sectionSlug] = initialData[key] as RepeatableEntryData[];
              }
            }
          }
        });

        setRepeatableData(initialRepeatableData);

      } catch (err: unknown) {
        console.error('Failed to fetch data:', err);

        // Check for specific error types
        const error = err as { response?: { status?: number } };
        if (error.response?.status === 401) {
          setError('You are not logged in or your session has expired. Please log in again.');
        } else if (error.response?.status === 404) {
          setError('Agent profile not found. Please complete your registration first.');
        } else {
          setError('Failed to load profile. Please try again.');
        }
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  const handleCancel = () => {
    router.push('/agent/dashboard');
  };

  const handleSave = async () => {
    try {
      setIsSaving(true);
      setFormErrors({});
      setRepeatableErrors({});

      // Validate required fields for regular sections
      const errors: Record<string, string> = {};
      const repErrors: Record<string, Record<string, Record<string, string>>> = {};

      sections.forEach(section => {
        const sectionFields = Array.isArray(section.fields) ? section.fields : [];
        if (section.isRepeatable) {
          // Validate repeatable section entries
          const entries = repeatableData[section.slug] || [{}];
          entries.forEach((entry, entryIndex) => {
            sectionFields.forEach(field => {
              if (field && field.isActive && !field.isSearchableOnly) {
                const err = validateFieldValue(field, entry[field.slug]);
                if (err) {
                  if (!repErrors[section.slug]) repErrors[section.slug] = {};
                  if (!repErrors[section.slug][entryIndex]) repErrors[section.slug][entryIndex] = {};
                  repErrors[section.slug][entryIndex][field.slug] = err;
                }
              }
            });
          });
        } else {
          // Validate regular section fields
          sectionFields.forEach(field => {
            if (field && field.isActive && !field.isSearchableOnly) {
              const err = validateFieldValue(field, formData[field.slug]);
              if (err) {
                errors[field.slug] = err;
              }
            }
          });
        }
      });

      const hasErrors = Object.keys(errors).length > 0;
      const hasRepeatableErrors = Object.keys(repErrors).length > 0;

      if (hasErrors || hasRepeatableErrors) {
        setFormErrors(errors);
        setRepeatableErrors(repErrors);
        // Scroll to first error
        if (hasErrors) {
          const firstErrorField = Object.keys(errors)[0];
          const errorElement = document.querySelector(`[data-field-slug="${firstErrorField}"]`);
          errorElement?.scrollIntoView({ behavior: 'smooth', block: 'center' });
        } else if (hasRepeatableErrors) {
          const firstSection = Object.keys(repErrors)[0];
          const sectionElement = document.getElementById(firstSection);
          sectionElement?.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
        return;
      }

      // Convert formData to field values array
      const fieldValues: FieldValueInput[] = Object.entries(formData).map(([fieldSlug, value]) => ({
        fieldSlug,
        value: value as string | number | boolean | string[] | Record<string, unknown> | null,
      }));

      // Add repeatable section data as a special field value
      Object.entries(repeatableData).forEach(([sectionSlug, entries]) => {
        // Filter out empty entries (entries with no filled fields)
        const nonEmptyEntries = entries.filter(entry =>
          Object.values(entry).some(v => v !== undefined && v !== null && v !== '')
        );

        if (nonEmptyEntries.length > 0) {
          fieldValues.push({
            fieldSlug: `${sectionSlug}_entries`,
            value: nonEmptyEntries,
          });
        }
      });

      // Save field values to API
      await agentsService.saveFieldValues(fieldValues);

      // Also update main profile fields (phone, email) to keep them in sync
      const profileUpdates: Partial<{ phone: string | null; email: string | null }> = {};

      const phoneFieldSlugs = ['phone_number', 'cell_number', 'office_number', 'phone'];
      for (const slug of phoneFieldSlugs) {
        const phoneValue = formData[slug];
        if (phoneValue !== undefined) {
          profileUpdates.phone = phoneValue === '' ? null : (phoneValue as string);
          break;
        }
      }

      if (Object.keys(profileUpdates).length > 0) {
        await agentsService.updateProfile(profileUpdates);
      }

      // Auto-submit for verification (status: NONE or REJECTED → PENDING_REVIEW)
      const status = agentProfile?.verificationStatus;
      if (!status || status === 'NONE' || status === 'REJECTED') {
        try {
          await usersService.submitForVerification();
        } catch {
          // If submit fails (e.g. already pending), still proceed
        }
      }

      router.push('/agent/dashboard');
    } catch (err) {
      console.error('Failed to save:', err);
      setError('Failed to save profile. Please try again.');
    } finally {
      setIsSaving(false);
    }
  };

  const handleFieldChange = (fieldSlug: string, value: unknown) => {
    setFormData(prev => ({ ...prev, [fieldSlug]: value }));
    // Clear error when field is modified
    if (formErrors[fieldSlug]) {
      setFormErrors(prev => {
        const newErrors = { ...prev };
        delete newErrors[fieldSlug];
        return newErrors;
      });
    }
  };

  const handleRepeatableChange = (sectionSlug: string, entries: RepeatableEntryData[]) => {
    setRepeatableData(prev => ({ ...prev, [sectionSlug]: entries }));
    // Clear errors for this section when modified
    if (repeatableErrors[sectionSlug]) {
      setRepeatableErrors(prev => {
        const newErrors = { ...prev };
        delete newErrors[sectionSlug];
        return newErrors;
      });
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center h-[calc(100vh-180px)]">
        <div className="flex flex-col items-center gap-4">
          <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#E58625]"></div>
          <p className="text-[14px] font-serif text-[#00293D]/70">Loading profile sections...</p>
        </div>
      </div>
    );
  }

  if (error && sections.length === 0) {
    return (
      <div className="flex items-center justify-center h-[calc(100vh-180px)]">
        <div className="bg-white rounded-[20px] p-8 shadow-[0px_10px_20px_rgba(217,217,217,0.5)] max-w-md text-center">
          <div className="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-4">
            <svg className="w-8 h-8 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
          </div>
          <h2 className="text-[18px] font-bold font-serif text-[#00293D] mb-2">Unable to Load Profile</h2>
          <p className="text-[14px] font-serif text-[#00293D]/70 mb-4">{error}</p>
          <button
            onClick={() => window.location.reload()}
            className="px-6 py-2 bg-[#E58625] rounded-full text-[14px] font-semibold font-serif text-white hover:bg-[#E58625]/90 transition-colors"
          >
            Try Again
          </button>
        </div>
      </div>
    );
  }

  return (
    <div>
      <MobileBackButton label="Back" fallbackHref="/agent/dashboard" alwaysShow />
    <div className="flex gap-6 h-[calc(100vh-180px)]">
      {/* Left Sidebar - Quick Links */}
      <div className="w-[220px] flex-shrink-0 hidden lg:block h-full overflow-y-auto scrollbar-thin">
        <QuickLinks scrollContainerRef={scrollContainerRef} sections={sections} />
      </div>

      {/* Main Content - Scrollable */}
      <div
        ref={scrollContainerRef}
        className="flex-1 overflow-y-auto scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent"
      >
        {/* Inner container with padding for shadow visibility */}
        <div className="space-y-6 p-2">
        {/* Error Banner */}
        {error && (
          <div className="bg-red-50 border border-red-200 rounded-[15px] p-4 flex items-center gap-3">
            <svg className="w-5 h-5 text-red-500 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
            </svg>
            <p className="text-[14px] font-serif text-red-700">{error}</p>
          </div>
        )}

        {/* Dynamic Sections */}
        {sections.map((section) =>
          section.isRepeatable ? (
            <RepeatableSection
              key={section.id}
              section={section}
              entries={repeatableData[section.slug] || [{}]}
              onChange={handleRepeatableChange}
              errors={repeatableErrors[section.slug]}
            />
          ) : (
            <DynamicSection
              key={section.id}
              section={section}
              formData={formData}
              onChange={handleFieldChange}
              errors={formErrors}
            />
          )
        )}

        {/* Empty State */}
        {sections.length === 0 && !loading && (
          <div className="bg-white rounded-[20px] p-8 shadow-[0px_10px_20px_rgba(217,217,217,0.5)] text-center">
            <div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center mx-auto mb-4">
              <svg className="w-8 h-8 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
              </svg>
            </div>
            <h2 className="text-[18px] font-bold font-serif text-[#00293D] mb-2">No Profile Sections Available</h2>
            <p className="text-[14px] font-serif text-[#00293D]/70">
              Profile sections have not been configured for your agent type yet.
            </p>
          </div>
        )}

        {/* Action Buttons */}
        {sections.length > 0 && (
          <div className="flex justify-end gap-4 pb-6">
            <button
              onClick={handleCancel}
              disabled={isSaving}
              className="px-8 py-3 border border-[#00293D]/20 rounded-full text-[14px] font-semibold font-serif text-[#00293D] hover:bg-gray-50 transition-colors disabled:opacity-50"
            >
              Cancel
            </button>
            <button
              onClick={handleSave}
              disabled={isSaving}
              className="px-8 py-3 bg-[#E58625] rounded-full text-[14px] font-semibold font-serif text-white hover:bg-[#E58625]/90 transition-colors disabled:opacity-50 flex items-center gap-2"
            >
              {isSaving && (
                <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
              )}
              {(() => {
                const isApproved = agentProfile?.verificationStatus === 'APPROVED';
                if (isSaving) return isApproved ? 'Saving...' : 'Submitting...';
                return isApproved ? 'Save Changes' : 'Submit for Review';
              })()}
            </button>
          </div>
        )}
        </div>
      </div>
    </div>
    </div>
  );
}
