import { Plus, Trash2 } from "lucide-react";
import { useState } from "react";
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 { Textarea } from "@/components/ui/textarea";
import { Card } from "@/components/ui/card";
import { useUnitPreferences } from "@/hooks/useUnitPreferences";
import { toast } from "sonner";
import { 
  convertValueToMetric, 
  convertValueFromMetric, 
  detectUnitType,
  getMetricUnit,
  getDisplayUnit
} from "@/lib/units";
import { validateMetricUnit } from "@/lib/unitValidation";
import { getErrorMessage } from "@/lib/errorHandler";

interface CoasterStat {
  stat_name: string;
  stat_value: number;
  unit?: string;
  category?: string;
  description?: string;
  display_order: number;
}

interface CoasterStatsEditorProps {
  stats: CoasterStat[];
  onChange: (stats: CoasterStat[]) => void;
  categories?: string[];
}

const DEFAULT_CATEGORIES = ['Speed', 'Height', 'Length', 'Forces', 'Capacity', 'Duration', 'Other'];
const COMMON_STATS = [
  { name: 'Max Speed', unit: 'km/h', category: 'Speed' },
  { name: 'Max Height', unit: 'm', category: 'Height' },
  { name: 'Drop Height', unit: 'm', category: 'Height' },
  { name: 'Track Length', unit: 'm', category: 'Length' },
  { name: 'Max G-Force', unit: 'G', category: 'Forces' },
  { name: 'Max Negative G-Force', unit: 'G', category: 'Forces' },
  { name: 'Ride Duration', unit: 'seconds', category: 'Duration' },
  { name: 'Inversions', unit: 'count', category: 'Other' },
];

export function CoasterStatsEditor({ 
  stats, 
  onChange, 
  categories = DEFAULT_CATEGORIES 
}: CoasterStatsEditorProps) {
  const { preferences } = useUnitPreferences();
  const [unitErrors, setUnitErrors] = useState<Record<number, string>>({});
  
  const addStat = () => {
    onChange([
      ...stats,
      {
        stat_name: '',
        stat_value: 0,
        unit: '',
        category: categories[0],
        description: '',
        display_order: stats.length
      }
    ]);
  };

  const addCommonStat = (commonStat: typeof COMMON_STATS[0]) => {
    onChange([
      ...stats,
      {
        stat_name: commonStat.name,
        stat_value: 0,
        unit: commonStat.unit,
        category: commonStat.category,
        description: '',
        display_order: stats.length
      }
    ]);
  };

  const removeStat = (index: number) => {
    const newStats = stats.filter((_, i) => i !== index);
    onChange(newStats.map((stat, i) => ({ ...stat, display_order: i })));
  };

  const updateStat = (index: number, field: keyof CoasterStat, value: string | number | boolean | null | undefined) => {
    const newStats = [...stats];
    
    // Ensure unit is metric when updating unit field
    if (field === 'unit' && value && typeof value === 'string') {
      try {
        validateMetricUnit(value, 'Unit');
        newStats[index] = { ...newStats[index], unit: value };
        // Clear error for this index
        setUnitErrors(prev => {
          const updated = { ...prev };
          delete updated[index];
          return updated;
        });
      } catch (error: unknown) {
        const message = getErrorMessage(error);
        toast.error(message);
        // Store error for visual feedback
        setUnitErrors(prev => ({ ...prev, [index]: message }));
        return;
      }
    } else {
      newStats[index] = { ...newStats[index], [field]: value };
    }
    
    onChange(newStats);
  };

  // Get display value (convert from metric to user's preferred units)
  const getDisplayValue = (stat: CoasterStat): string => {
    if (!stat.stat_value || !stat.unit) return String(stat.stat_value || '');
    
    const numValue = Number(stat.stat_value);
    if (isNaN(numValue)) return String(stat.stat_value);
    
    const unitType = detectUnitType(stat.unit);
    if (unitType === 'unknown') return String(stat.stat_value);
    
    // stat.unit is the metric unit (e.g., "km/h")
    // Get the display unit based on user preference (e.g., "mph" for imperial)
    const displayUnit = getDisplayUnit(stat.unit, preferences.measurement_system);
    
    // Convert from metric to display unit
    const displayValue = convertValueFromMetric(numValue, displayUnit, stat.unit);
    
    return String(displayValue);
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <Label>Coaster Statistics</Label>
        <div className="flex gap-2">
          <Select onValueChange={(value) => {
            const commonStat = COMMON_STATS.find(s => s.name === value);
            if (commonStat) addCommonStat(commonStat);
          }}>
            <SelectTrigger className="w-[200px]">
              <SelectValue placeholder="Add common stat..." />
            </SelectTrigger>
            <SelectContent>
              {COMMON_STATS.map(stat => (
                <SelectItem key={stat.name} value={stat.name}>
                  {stat.name} ({stat.unit})
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button type="button" variant="outline" size="sm" onClick={addStat}>
            <Plus className="h-4 w-4 mr-2" />
            Add Custom
          </Button>
        </div>
      </div>

      {stats.length === 0 ? (
        <Card className="p-6 text-center text-muted-foreground">
          No statistics added yet. Add a common stat or create a custom one.
        </Card>
      ) : (
        <div className="space-y-3">
          {stats.map((stat, index) => (
            <Card key={index} className="p-4">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div>
                  <Label className="text-xs">Statistic Name</Label>
                  <Input
                    value={stat.stat_name}
                    onChange={(e) => updateStat(index, 'stat_name', e.target.value)}
                    placeholder="e.g., Max Speed"
                  />
                </div>

                <div className="grid grid-cols-2 gap-2">
                  <div>
                    <Label className="text-xs">Value</Label>
                    <Input
                      type="number"
                      step="0.01"
                      value={getDisplayValue(stat)}
                      onChange={(e) => {
                        const inputValue = e.target.value;
                        const numValue = parseFloat(inputValue);
                        
                        if (!isNaN(numValue) && stat.unit) {
                          // Determine what unit the user is entering (based on their preference)
                          const displayUnit = getDisplayUnit(stat.unit, preferences.measurement_system);
                          // Convert from user's input unit to metric for storage
                          const metricValue = convertValueToMetric(numValue, displayUnit);
                          updateStat(index, 'stat_value', metricValue);
                        } else {
                          updateStat(index, 'stat_value', numValue || 0);
                        }
                      }}
                      placeholder="0"
                    />
                    {stat.unit && detectUnitType(stat.unit) !== 'unknown' && (
                      <p className="text-xs text-muted-foreground mt-1">
                        Enter in {getDisplayUnit(stat.unit, preferences.measurement_system)}
                      </p>
                    )}
                  </div>
                  <div>
                    <Label className="text-xs">Unit</Label>
                    <Input
                      value={stat.unit || ''}
                      onChange={(e) => updateStat(index, 'unit', e.target.value)}
                      placeholder="km/h, m, G..."
                      className={unitErrors[index] ? 'border-destructive' : ''}
                    />
                    {unitErrors[index] && (
                      <p className="text-xs text-destructive mt-1">{unitErrors[index]}</p>
                    )}
                    <p className="text-xs text-muted-foreground mt-1">
                      ⚠️ Use metric units only: km/h, m, cm, kg, G, celsius
                    </p>
                  </div>
                </div>

                <div>
                  <Label className="text-xs">Category</Label>
                  <Select
                    value={stat.category || ''}
                    onValueChange={(value) => updateStat(index, 'category', value)}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Select category" />
                    </SelectTrigger>
                    <SelectContent>
                      {categories.map(cat => (
                        <SelectItem key={cat} value={cat}>{cat}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>

                <div className="flex items-end">
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => removeStat(index)}
                    className="ml-auto"
                  >
                    <Trash2 className="h-4 w-4 text-destructive mr-2" />
                    Remove
                  </Button>
                </div>

                <div className="md:col-span-2">
                  <Label className="text-xs">Description (optional)</Label>
                  <Textarea
                    value={stat.description || ''}
                    onChange={(e) => updateStat(index, 'description', e.target.value)}
                    placeholder="Additional context about this statistic..."
                    rows={2}
                  />
                </div>
              </div>
            </Card>
          ))}
        </div>
      )}
    </div>
  );
}

/**
 * Validates coaster stats before submission
 */
export function validateCoasterStats(stats: CoasterStat[]): { valid: boolean; errors: string[] } {
  const errors: string[] = [];
  
  stats.forEach((stat, index) => {
    if (!stat.stat_name?.trim()) {
      errors.push(`Stat ${index + 1}: Name is required`);
    }
    if (stat.stat_value === null || stat.stat_value === undefined) {
      errors.push(`Stat ${index + 1} (${stat.stat_name}): Value is required`);
    }
    if (stat.unit) {
      try {
        validateMetricUnit(stat.unit, `Stat ${index + 1} (${stat.stat_name})`);
      } catch (error: unknown) {
        errors.push(getErrorMessage(error));
      }
    }
  });
  
  return { valid: errors.length === 0, errors };
}
