import { useState, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import { Switch } from '@/components/ui/switch';
import { Skeleton } from '@/components/ui/skeleton';
import { useAuth } from '@/hooks/useAuth';
import { useProfile } from '@/hooks/useProfile';
import { useUnitPreferences } from '@/hooks/useUnitPreferences';
import { supabase } from '@/integrations/supabase/client';
import { handleError, handleSuccess, AppError } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
import { MapPin, Calendar, Accessibility, Ruler } from 'lucide-react';
import type { LocationFormData, AccessibilityOptions, ParkOption } from '@/types/location';
import {
  locationFormSchema,
  accessibilityOptionsSchema,
  parkOptionSchema,
  DEFAULT_ACCESSIBILITY_OPTIONS,
  COMMON_TIMEZONES
} from '@/lib/locationValidation';

export function LocationTab() {
  const { user } = useAuth();
  const { data: profile, refreshProfile } = useProfile(user?.id);
  const { preferences: unitPreferences, updatePreferences: updateUnitPreferences } = useUnitPreferences();
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [parks, setParks] = useState<ParkOption[]>([]);
  const [accessibility, setAccessibility] = useState<AccessibilityOptions>(DEFAULT_ACCESSIBILITY_OPTIONS);
  
  const form = useForm<LocationFormData>({
    resolver: zodResolver(locationFormSchema),
    defaultValues: {
      preferred_pronouns: profile?.preferred_pronouns || null,
      timezone: profile?.timezone || 'UTC',
      preferred_language: profile?.preferred_language || 'en',
      personal_location: profile?.personal_location || null,
      home_park_id: profile?.home_park_id || null
    }
  });

  useEffect(() => {
    if (user && profile) {
      form.reset({
        preferred_pronouns: profile.preferred_pronouns || null,
        timezone: profile.timezone || 'UTC',
        preferred_language: profile.preferred_language || 'en',
        personal_location: profile.personal_location || null,
        home_park_id: profile.home_park_id || null
      });
    }
  }, [profile, form]);

  useEffect(() => {
    if (user) {
      fetchParks();
      fetchAccessibilityPreferences();
    }
  }, [user]);

  const fetchParks = async () => {
    if (!user) return;

    try {
      const { data, error } = await supabase
        .from('parks')
        .select('id, name, locations(city, state_province, country)')
        .order('name');
      
      if (error) {
        logger.error('Failed to fetch parks list', {
          userId: user.id,
          action: 'fetch_parks',
          error: error.message,
          errorCode: error.code
        });
        throw error;
      }

      const validatedParks = (data || [])
        .map(park => {
          try {
            return parkOptionSchema.parse({
              id: park.id,
              name: park.name,
              location: park.locations ? {
                city: park.locations.city,
                state_province: park.locations.state_province,
                country: park.locations.country
              } : undefined
            });
          } catch {
            return null;
          }
        })
        .filter((park): park is ParkOption => park !== null);

      setParks(validatedParks);
      
      logger.info('Parks list loaded', {
        userId: user.id,
        action: 'fetch_parks',
        count: validatedParks.length
      });
    } catch (error: unknown) {
      logger.error('Error fetching parks', {
        userId: user.id,
        action: 'fetch_parks',
        error: error instanceof Error ? error.message : String(error)
      });

      handleError(error, {
        action: 'Load parks list',
        userId: user.id
      });
    }
  };

  const fetchAccessibilityPreferences = async () => {
    if (!user) return;

    try {
      const { data, error } = await supabase
        .from('user_preferences')
        .select('accessibility_options')
        .eq('user_id', user.id)
        .maybeSingle();
      
      if (error && error.code !== 'PGRST116') {
        logger.error('Failed to fetch accessibility preferences', {
          userId: user.id,
          action: 'fetch_accessibility_preferences',
          error: error.message,
          errorCode: error.code
        });
        throw error;
      }

      if (data?.accessibility_options) {
        const validated = accessibilityOptionsSchema.parse(data.accessibility_options);
        setAccessibility(validated);
      }

      logger.info('Accessibility preferences loaded', {
        userId: user.id,
        action: 'fetch_accessibility_preferences'
      });
    } catch (error: unknown) {
      logger.error('Error fetching accessibility preferences', {
        userId: user.id,
        action: 'fetch_accessibility_preferences',
        error: error instanceof Error ? error.message : String(error)
      });

      handleError(error, {
        action: 'Load accessibility preferences',
        userId: user.id
      });
    } finally {
      setLoading(false);
    }
  };

  const onSubmit = async (data: LocationFormData) => {
    if (!user) return;

    setSaving(true);

    try {
      const validatedData = locationFormSchema.parse(data);
      const validatedAccessibility = accessibilityOptionsSchema.parse(accessibility);

      const previousProfile = {
        personal_location: profile?.personal_location,
        home_park_id: profile?.home_park_id,
        timezone: profile?.timezone,
        preferred_language: profile?.preferred_language,
        preferred_pronouns: profile?.preferred_pronouns
      };

      const { error: profileError } = await supabase
        .from('profiles')
        .update({
          preferred_pronouns: validatedData.preferred_pronouns || null,
          timezone: validatedData.timezone,
          preferred_language: validatedData.preferred_language,
          personal_location: validatedData.personal_location || null,
          home_park_id: validatedData.home_park_id || null,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', user.id);
      
      if (profileError) {
        logger.error('Failed to update profile', {
          userId: user.id,
          action: 'update_profile_location',
          error: profileError.message,
          errorCode: profileError.code
        });
        throw profileError;
      }

      const { error: accessibilityError } = await supabase
        .from('user_preferences')
        .update({
          accessibility_options: validatedAccessibility,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', user.id);
      
      if (accessibilityError) {
        logger.error('Failed to update accessibility preferences', {
          userId: user.id,
          action: 'update_accessibility_preferences',
          error: accessibilityError.message,
          errorCode: accessibilityError.code
        });
        throw accessibilityError;
      }

      await updateUnitPreferences(unitPreferences);

      await supabase.from('profile_audit_log').insert([{
        user_id: user.id,
        changed_by: user.id,
        action: 'location_info_updated',
        changes: JSON.parse(JSON.stringify({
          previous: {
            profile: previousProfile,
            accessibility: DEFAULT_ACCESSIBILITY_OPTIONS
          },
          updated: {
            profile: validatedData,
            accessibility: validatedAccessibility
          },
          timestamp: new Date().toISOString()
        }))
      }]);

      await refreshProfile();
      
      logger.info('Location and info settings updated', {
        userId: user.id,
        action: 'update_location_info'
      });

      handleSuccess(
        'Settings saved',
        'Your location, personal information, accessibility, and unit preferences have been updated.'
      );
    } catch (error: unknown) {
      logger.error('Error saving location settings', {
        userId: user.id,
        action: 'save_location_settings',
        error: error instanceof Error ? error.message : String(error)
      });

      if (error instanceof z.ZodError) {
        handleError(
          new AppError(
            'Invalid settings',
            'VALIDATION_ERROR',
            error.issues.map(i => i.message).join(', ')
          ),
          { action: 'Validate location settings', userId: user.id }
        );
      } else {
        handleError(error, {
          action: 'Save location settings',
          userId: user.id
        });
      }
    } finally {
      setSaving(false);
    }
  };

  const updateAccessibility = (key: keyof AccessibilityOptions, value: any) => {
    setAccessibility(prev => ({ ...prev, [key]: value }));
  };

  if (loading) {
    return (
      <div className="space-y-8">
        <Card>
          <CardHeader>
            <Skeleton className="h-6 w-48" />
            <Skeleton className="h-4 w-full max-w-md" />
          </CardHeader>
          <CardContent className="space-y-4">
            <Skeleton className="h-12 w-full" />
            <Skeleton className="h-12 w-full" />
          </CardContent>
        </Card>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
        {/* Location Settings + Personal Information Grid */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          {/* Location Settings */}
          <Card>
            <CardHeader>
              <div className="flex items-center gap-2">
                <MapPin className="w-5 h-5" />
                <CardTitle>Location Settings</CardTitle>
              </div>
              <CardDescription>
                Set your location for better personalized content and timezone display.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="space-y-2">
                <Label htmlFor="personal_location">Your Location</Label>
                <Input 
                  id="personal_location" 
                  {...form.register('personal_location')} 
                  placeholder="e.g., San Francisco, CA or Berlin, Germany" 
                />
                {form.formState.errors.personal_location && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.personal_location.message}
                  </p>
                )}
                <p className="text-sm text-muted-foreground">
                  Your personal location (optional, displayed as text)
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="home_park_id">Home Park</Label>
                <Select 
                  value={form.watch('home_park_id') || undefined} 
                  onValueChange={value => form.setValue('home_park_id', value)}
                >
                  <SelectTrigger>
                    <SelectValue placeholder="Select your home park" />
                  </SelectTrigger>
                  <SelectContent>
                    {parks.map(park => (
                      <SelectItem key={park.id} value={park.id}>
                        {park.name}
                        {park.location && (
                          <>
                            {park.location.city && `, ${park.location.city}`}
                            {park.location.state_province && `, ${park.location.state_province}`}
                            {`, ${park.location.country}`}
                          </>
                        )}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {form.formState.errors.home_park_id && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.home_park_id.message}
                  </p>
                )}
                <p className="text-sm text-muted-foreground">
                  The theme park you visit most often or consider your "home" park
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="timezone">Timezone</Label>
                <Select 
                  value={form.watch('timezone')} 
                  onValueChange={value => form.setValue('timezone', value)}
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {COMMON_TIMEZONES.map(tz => (
                      <SelectItem key={tz} value={tz}>
                        {tz}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {form.formState.errors.timezone && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.timezone.message}
                  </p>
                )}
                <p className="text-sm text-muted-foreground">
                  Used to display dates and times in your local timezone.
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="preferred_language">Preferred Language</Label>
                <Select 
                  value={form.watch('preferred_language')} 
                  onValueChange={value => form.setValue('preferred_language', value)}
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="en">English</SelectItem>
                    <SelectItem value="es">Español</SelectItem>
                    <SelectItem value="fr">Français</SelectItem>
                    <SelectItem value="de">Deutsch</SelectItem>
                    <SelectItem value="it">Italiano</SelectItem>
                    <SelectItem value="pt">Português</SelectItem>
                    <SelectItem value="ja">日本語</SelectItem>
                    <SelectItem value="zh">中文</SelectItem>
                  </SelectContent>
                </Select>
                {form.formState.errors.preferred_language && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.preferred_language.message}
                  </p>
                )}
              </div>
            </CardContent>
          </Card>

          {/* Personal Information */}
          <Card>
            <CardHeader>
              <div className="flex items-center gap-2">
                <Calendar className="w-5 h-5" />
                <CardTitle>Personal Information</CardTitle>
              </div>
              <CardDescription>
                Optional personal information that can be displayed on your profile.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="space-y-2">
                <Label htmlFor="preferred_pronouns">Preferred Pronouns</Label>
                <Input 
                  id="preferred_pronouns" 
                  {...form.register('preferred_pronouns')} 
                  placeholder="e.g., they/them, she/her, he/him" 
                />
                {form.formState.errors.preferred_pronouns && (
                  <p className="text-sm text-destructive">
                    {form.formState.errors.preferred_pronouns.message}
                  </p>
                )}
                <p className="text-sm text-muted-foreground">
                  How you'd like others to refer to you.
                </p>
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Unit Preferences + Accessibility Options Grid */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          {/* Unit Preferences */}
          <Card>
            <CardHeader>
              <div className="flex items-center gap-2">
                <Ruler className="w-5 h-5" />
                <CardTitle>Units & Measurements</CardTitle>
              </div>
              <CardDescription>
                Choose your preferred measurement system for displaying distances, speeds, and other measurements.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="space-y-3">
                <Label>Measurement System</Label>
                <Select 
                  value={unitPreferences.measurement_system} 
                  onValueChange={(value: 'metric' | 'imperial') => 
                    updateUnitPreferences({ measurement_system: value })
                  }
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="metric">Metric (km/h, meters, cm)</SelectItem>
                    <SelectItem value="imperial">Imperial (mph, feet, inches)</SelectItem>
                  </SelectContent>
                </Select>
                <p className="text-sm text-muted-foreground">
                  All measurements in the database are stored in metric and converted for display.
                </p>
              </div>
            </CardContent>
          </Card>

          {/* Accessibility Options */}
          <Card>
            <CardHeader>
              <div className="flex items-center gap-2">
                <Accessibility className="w-5 h-5" />
                <CardTitle>Accessibility Options</CardTitle>
              </div>
              <CardDescription>
                Customize the interface to meet your accessibility needs.
              </CardDescription>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="space-y-3">
                <Label>Font Size</Label>
                <Select 
                  value={accessibility.font_size} 
                  onValueChange={(value: 'small' | 'medium' | 'large') => 
                    updateAccessibility('font_size', value)
                  }
                >
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="small">Small</SelectItem>
                    <SelectItem value="medium">Medium (Default)</SelectItem>
                    <SelectItem value="large">Large</SelectItem>
                  </SelectContent>
                </Select>
              </div>

              <div className="flex items-center justify-between">
                <div className="space-y-1">
                  <Label>High Contrast</Label>
                  <p className="text-sm text-muted-foreground">
                    Increase contrast for better visibility
                  </p>
                </div>
                <Switch 
                  checked={accessibility.high_contrast} 
                  onCheckedChange={checked => updateAccessibility('high_contrast', checked)} 
                />
              </div>

              <div className="flex items-center justify-between">
                <div className="space-y-1">
                  <Label>Reduced Motion</Label>
                  <p className="text-sm text-muted-foreground">
                    Minimize animations and transitions
                  </p>
                </div>
                <Switch 
                  checked={accessibility.reduced_motion} 
                  onCheckedChange={checked => updateAccessibility('reduced_motion', checked)} 
                />
              </div>
            </CardContent>
          </Card>
        </div>

        {/* Save Button */}
        <div className="flex justify-end">
          <Button type="submit" disabled={saving}>
            {saving ? 'Saving...' : 'Save Settings'}
          </Button>
        </div>
      </form>
    </div>
  );
}
