import { useState, useCallback, useEffect } from 'react';
import api from '../api';
import type { MapPoint, ParcelGeometry } from '../components/UiComponents/MapView';
import { wgs84ToLV95 } from '../components/UiComponents/MapView/LV95Converter';

// Parcel search response interfaces
export interface ParcelSearchResponse {
  parcel: {
    id: string;
    egrid?: string;
    number?: string;
    name?: string;
    identnd?: string;
    canton?: string;
    municipality_code?: number;
    municipality_name?: string;
    address?: string;
    perimeter?: {
      closed: boolean;
      punkte: Array<{
        koordinatensystem: string;
        x: number;
        y: number;
        z: number | null;
      }>;
    };
    area_m2?: number;
    centroid?: { x: number; y: number };
    geoportal_url?: string;
    realestate_type?: string | null;
  };
  map_view: {
    center: { x: number; y: number };
    zoom_bounds: {
      min_x: number;
      min_y: number;
      max_x: number;
      max_y: number;
    };
    geometry_geojson: {
      type: string;
      geometry: {
        type: string;
        coordinates: number[][][];
      };
      properties: {
        id: string;
        egrid?: string;
        number?: string;
      };
    };
  };
  adjacent_parcels?: Array<{
    id: string;
    egrid?: string;
    number?: string;
    perimeter?: {
      closed: boolean;
      punkte: Array<{
        koordinatensystem: string;
        x: number;
        y: number;
        z: number | null;
      }>;
    };
    geometry_geojson?: {
      type: string;
      geometry: {
        type: string;
        coordinates: number[][][];
      };
      properties: {
        id: string;
        egrid?: string;
        number?: string;
      };
    };
  }>;
}

// Command response interface
export interface CommandResponse {
  success: boolean;
  intent?: string;
  entity?: string;
  result?: any;
  error?: string;
}

// Project interfaces
export interface Projekt {
  id: string;
  mandateId?: string;
  label: string;
  statusProzess?: string;
  perimeter?: any;
  baulinie?: any;
  parzellen?: any[];
  dokumente?: any[];
  kontextInformationen?: any[];
}

export interface CreateProjektResponse {
  projekt: Projekt;
  parzellen?: any[];
}

export interface AddParcelResponse {
  projekt: Projekt;
  parzelle: any;
}

// Main PEK hook
export function usePek() {
  // Location input state - separate fields
  const [kanton, setKanton] = useState<string>('');
  const [gemeinde, setGemeinde] = useState<string>('');
  const [adresse, setAdresse] = useState<string>('');
  const [isGettingLocation, setIsGettingLocation] = useState(false);
  const [locationError, setLocationError] = useState<string | null>(null);
  
  // Legacy locationInput for backward compatibility (combines fields)
  const locationInput = [kanton, gemeinde, adresse].filter(Boolean).join(', ');
  const setLocationInput = (value: string) => {
    // Parse combined input if needed (for map clicks, etc.)
    const parts = value.split(',').map(p => p.trim());
    if (parts.length >= 3) {
      setKanton(parts[0]);
      setGemeinde(parts[1]);
      setAdresse(parts.slice(2).join(', '));
    } else {
      setAdresse(value);
    }
  };

  // Parcel search state
  const [selectedParcels, setSelectedParcels] = useState<ParcelSearchResponse[]>([]);
  const [isSearchingParcel, setIsSearchingParcel] = useState(false);
  const [parcelSearchError, setParcelSearchError] = useState<string | null>(null);

  // Map view state
  const [mapCenter, setMapCenter] = useState<MapPoint | null>(null);
  const [mapZoomBounds, setMapZoomBounds] = useState<{
    min_x: number;
    min_y: number;
    max_x: number;
    max_y: number;
  } | null>(null);
  const [parcelGeometries, setParcelGeometries] = useState<ParcelGeometry[]>([]);

  // Command processing state
  const [commandInput, setCommandInput] = useState<string>('');
  const [isProcessingCommand, setIsProcessingCommand] = useState(false);
  const [commandResults, setCommandResults] = useState<any[]>([]);
  const [commandError, setCommandError] = useState<string | null>(null);

  // Project state
  const [currentProjekt, setCurrentProjekt] = useState<Projekt | null>(null);
  const [isCreatingProjekt, setIsCreatingProjekt] = useState(false);
  const [isAddingParcel, setIsAddingParcel] = useState(false);
  const [projektError, setProjektError] = useState<string | null>(null);

  // Panel state
  const [isPanelOpen, setIsPanelOpen] = useState(false);

  // Update parcel geometries when selected parcels change
  // Ensure all selected parcels are marked as selected and not as adjacent
  useEffect(() => {
    const selectedParcelIds = new Set(selectedParcels.map(p => p.parcel.id));
    
    setParcelGeometries(prev => prev.map(geo => {
      const isSelected = selectedParcelIds.has(geo.id);
      // If parcel is selected, it should not be marked as adjacent
      const isAdjacent = isSelected ? false : geo.isAdjacent;
      return { ...geo, isSelected, isAdjacent };
    }));
  }, [selectedParcels]);

  /**
   * Get current geolocation and directly search for parcel
   * Does not fill input fields, directly makes the request
   */
  const useCurrentLocation = useCallback(async () => {
    setIsGettingLocation(true);
    setLocationError(null);

    try {
      if (!navigator.geolocation) {
        throw new Error('Geolocation wird von Ihrem Browser nicht unterstützt');
      }

      return new Promise<void>((resolve, reject) => {
        navigator.geolocation.getCurrentPosition(
          async (position) => {
            try {
              // Convert WGS84 to LV95 using the converter function
              const lat = position.coords.latitude;
              const lon = position.coords.longitude;

              const lv95 = wgs84ToLV95(lat, lon);
              const locationString = `${Math.round(lv95.x)},${Math.round(lv95.y)}`;
              
              // Directly search for parcel without updating input fields
              await searchParcel(locationString, true);
              resolve();
            } catch (err: any) {
              setLocationError(err.message || 'Fehler beim Konvertieren der Koordinaten');
              reject(err);
            }
          },
          (error) => {
            let errorMessage = 'Fehler beim Abrufen der Position';
            switch (error.code) {
              case error.PERMISSION_DENIED:
                errorMessage = 'Zugriff auf Standort wurde verweigert';
                break;
              case error.POSITION_UNAVAILABLE:
                errorMessage = 'Standortinformationen nicht verfügbar';
                break;
              case error.TIMEOUT:
                errorMessage = 'Zeitüberschreitung beim Abrufen der Position';
                break;
            }
            setLocationError(errorMessage);
            reject(new Error(errorMessage));
          },
          {
            enableHighAccuracy: true,
            timeout: 10000,
            maximumAge: 0
          }
        );
      });
    } catch (err: any) {
      setLocationError(err.message || 'Fehler beim Abrufen der aktuellen Position');
      throw err;
    } finally {
      setIsGettingLocation(false);
    }
  }, []);

  /**
   * Search for parcel by location (address or coordinates)
   * Always includes adjacent parcels by default
   */
  const searchParcel = useCallback(async (location: string, includeAdjacent: boolean = true) => {
    if (!location.trim()) {
      setParcelSearchError('Bitte geben Sie einen Standort ein');
      return;
    }

    setIsSearchingParcel(true);
    setParcelSearchError(null);

    try {
      const response = await api.get('/api/realestate/parcel/search', {
        params: {
          location: location.trim(),
          include_adjacent: includeAdjacent
        }
      });

      const data: ParcelSearchResponse = response.data;

      // Debug logging
      if (import.meta.env.DEV) {
        console.log('📦 Parcel search response:', {
          hasMapView: !!data.map_view,
          hasGeometry: !!data.map_view?.geometry_geojson,
          hasPerimeter: !!data.parcel.perimeter,
          adjacentCount: data.adjacent_parcels?.length || 0
        });
      }

      // Add parcel to selected parcels array if not already selected
      // Update geometries within the callback to have access to updated selectedParcels
      setSelectedParcels(prev => {
        const exists = prev.some(p => p.parcel.id === data.parcel.id);
        if (exists) {
          return prev; // Already selected, don't add again
        }
        
        const updatedSelectedParcels = [...prev, data];
        const selectedParcelIds = new Set(updatedSelectedParcels.map(p => p.parcel.id));
        
        // Update geometries
        setParcelGeometries(currentGeometries => {
          const geometryMap = new Map<string, ParcelGeometry>();
          
          // Keep existing geometries
          currentGeometries.forEach(geo => {
            geometryMap.set(geo.id, geo);
          });
          
          // Update map center and zoom bounds
          if (data.map_view) {
            setMapCenter(data.map_view.center);
            setMapZoomBounds(data.map_view.zoom_bounds);

            // Main parcel - use geometry_geojson if available, otherwise use perimeter.punkte
            let mainParcelCoordinates: MapPoint[] = [];

            if (data.map_view.geometry_geojson?.geometry?.coordinates) {
              const coords = data.map_view.geometry_geojson.geometry.coordinates[0];
              if (Array.isArray(coords)) {
                mainParcelCoordinates = coords.map((coord: number[]) => ({
                  x: coord[0],
                  y: coord[1]
                }));
              }
            } else if (data.parcel.perimeter?.punkte) {
              mainParcelCoordinates = data.parcel.perimeter.punkte.map((p) => ({
                x: p.x,
                y: p.y
              }));
            }

            if (mainParcelCoordinates.length > 0) {
              geometryMap.set(data.parcel.id, {
                id: data.parcel.id,
                egrid: data.parcel.egrid,
                number: data.parcel.number,
                coordinates: mainParcelCoordinates,
                isSelected: true,
                isAdjacent: false
              });
            }

            // Add adjacent parcels, but skip if already selected
            if (data.adjacent_parcels && includeAdjacent && data.adjacent_parcels.length > 0) {
              data.adjacent_parcels.forEach((adjacent) => {
                // Skip if this adjacent parcel is already selected
                if (selectedParcelIds.has(adjacent.id)) {
                  // If it exists, mark as selected, not adjacent
                  const existingGeo = geometryMap.get(adjacent.id);
                  if (existingGeo) {
                    geometryMap.set(adjacent.id, {
                      ...existingGeo,
                      isSelected: true,
                      isAdjacent: false
                    });
                  }
                  if (import.meta.env.DEV) {
                    console.log(`⏭️ Skipping adjacent parcel ${adjacent.id} - already selected`);
                  }
                  return;
                }
                
                // Only add if not already in map
                if (!geometryMap.has(adjacent.id)) {
                  let adjCoordinates: MapPoint[] = [];

                  if (adjacent.geometry_geojson?.geometry?.coordinates) {
                    const coords = adjacent.geometry_geojson.geometry.coordinates[0];
                    if (Array.isArray(coords) && coords.length > 0) {
                      adjCoordinates = coords.map((coord: number[]) => ({
                        x: coord[0],
                        y: coord[1]
                      }));
                    }
                  } else if (adjacent.perimeter?.punkte) {
                    adjCoordinates = adjacent.perimeter.punkte.map((p) => ({
                      x: p.x,
                      y: p.y
                    }));
                  }

                  if (adjCoordinates.length >= 3) {
                    geometryMap.set(adjacent.id, {
                      id: adjacent.id,
                      egrid: adjacent.egrid,
                      number: adjacent.number,
                      coordinates: adjCoordinates,
                      isSelected: false,
                      isAdjacent: true
                    });
                  }
                }
              });
            }
          } else {
            // If no map_view, still try to use parcel data
            if (data.parcel.perimeter?.punkte) {
              const coordinates = data.parcel.perimeter.punkte.map((p) => ({
                x: p.x,
                y: p.y
              }));

              geometryMap.set(data.parcel.id, {
                id: data.parcel.id,
                egrid: data.parcel.egrid,
                number: data.parcel.number,
                coordinates,
                isSelected: true,
                isAdjacent: false
              });

              if (data.parcel.centroid) {
                setMapCenter(data.parcel.centroid);
              }
            }
          }
          
          // Update all geometries: mark selected ones and unmark adjacent for selected ones
          const updatedGeometries = Array.from(geometryMap.values()).map(geo => {
            const isSelected = selectedParcelIds.has(geo.id);
            return {
              ...geo,
              isSelected,
              isAdjacent: isSelected ? false : geo.isAdjacent
            };
          });
          
          if (import.meta.env.DEV) {
            console.log(`🗺️ Total geometries to display: ${updatedGeometries.length}`, {
              selected: updatedGeometries.filter(g => g.isSelected).length,
              adjacent: updatedGeometries.filter(g => g.isAdjacent).length
            });
          }
          
          return updatedGeometries;
        });
        
        return updatedSelectedParcels;
      });
      
      // Open panel when parcel is found
      setIsPanelOpen(true);

      return { success: true, data };
    } catch (err: any) {
      const errorMessage =
        err.response?.data?.detail || err.message || 'Fehler beim Suchen der Parzelle';
      setParcelSearchError(errorMessage);
      return { success: false, error: errorMessage };
    } finally {
      setIsSearchingParcel(false);
    }
  }, []);

  /**
   * Handle map click - search for parcel at clicked coordinates
   */
  const handleMapClick = useCallback(
    async (point: MapPoint) => {
      const locationString = `${point.x},${point.y}`;
      setLocationInput(locationString);
      await searchParcel(locationString, true); // Always include adjacent parcels
    },
    [searchParcel]
  );

  /**
   * Check if a parcel is selected
   */
  const isParcelSelected = useCallback((parcelId: string): boolean => {
    return selectedParcels.some(p => p.parcel.id === parcelId);
  }, [selectedParcels]);

  /**
   * Remove a parcel from selection
   */
  const removeParcel = useCallback((parcelId: string) => {
    setSelectedParcels(prev => prev.filter(p => p.parcel.id !== parcelId));
    // Update geometries to reflect deselection
    setParcelGeometries(prev => prev.map(geo => 
      geo.id === parcelId ? { ...geo, isSelected: false } : geo
    ));
  }, []);

  /**
   * Clear all selected parcels
   */
  const clearSelectedParcels = useCallback(() => {
    setSelectedParcels([]);
    // Update geometries to reflect deselection
    setParcelGeometries(prev => prev.map(geo => ({ ...geo, isSelected: false })));
  }, []);

  /**
   * Handle parcel click on map - toggle parcel selection
   */
  const handleParcelClick = useCallback(async (parcelId: string) => {
    // Check if parcel is already selected
    const isSelected = isParcelSelected(parcelId);
    
    if (isSelected) {
      // Remove from selection
      removeParcel(parcelId);
    } else {
      // Find the clicked parcel in the geometries
      const clickedParcel = parcelGeometries.find(p => p.id === parcelId);
      
      if (clickedParcel && clickedParcel.coordinates.length > 0) {
        // Use a point inside the parcel (first coordinate is always on the boundary, which is inside)
        const firstCoord = clickedParcel.coordinates[0];
        
        // Use first coordinate (guaranteed to be on/in the parcel) for search
        const locationString = `${firstCoord.x},${firstCoord.y}`;
        await searchParcel(locationString, true); // Always include adjacent parcels
      } else {
        // Fallback: try to search by parcel ID/EGRID if available
        // Check all selected parcels for adjacent parcels
        for (const selectedParcel of selectedParcels) {
          if (selectedParcel.adjacent_parcels) {
            const adjacentParcel = selectedParcel.adjacent_parcels.find(p => p.id === parcelId);
            if (adjacentParcel?.egrid) {
              // Search by EGRID
              await searchParcel(adjacentParcel.egrid, true);
              break;
            } else if (adjacentParcel?.number) {
              // Try searching by number (might need address context)
              await searchParcel(adjacentParcel.number, true);
              break;
            } else if (adjacentParcel?.id) {
              // Last resort: try searching by ID
              await searchParcel(adjacentParcel.id, true);
              break;
            }
          }
        }
      }
    }
  }, [parcelGeometries, selectedParcels, isParcelSelected, removeParcel, searchParcel]);

  /**
   * Process natural language command
   * Always includes the currently selected parcel if available
   */
  const processCommand = useCallback(async (userInput: string) => {
    if (!userInput.trim()) {
      setCommandError('Bitte geben Sie einen Befehl ein');
      return;
    }

    setIsProcessingCommand(true);
    setCommandError(null);

    // Add user message
    const userMessage = {
      id: `user-${Date.now()}`,
      role: 'user',
      message: userInput.trim(),
      timestamp: Date.now()
    };
    setCommandResults((prev) => [...prev, userMessage]);

    try {
      // Build request body with user input and selected parcel
      const requestBody: any = {
        userInput: userInput.trim()
      };

      // Always include the currently selected parcels if available
      if (selectedParcels.length > 0) {
        // Use first selected parcel for backward compatibility
        const firstParcel = selectedParcels[0];
        requestBody.selectedParcel = {
          id: firstParcel.parcel.id,
          egrid: firstParcel.parcel.egrid,
          number: firstParcel.parcel.number,
          name: firstParcel.parcel.name,
          identnd: firstParcel.parcel.identnd,
          canton: firstParcel.parcel.canton,
          municipality_code: firstParcel.parcel.municipality_code,
          municipality_name: firstParcel.parcel.municipality_name,
          address: firstParcel.parcel.address,
          area_m2: firstParcel.parcel.area_m2,
          centroid: firstParcel.parcel.centroid,
          geoportal_url: firstParcel.parcel.geoportal_url,
          realestate_type: firstParcel.parcel.realestate_type,
          // Include geometry data if available
          geometry_geojson: firstParcel.map_view?.geometry_geojson,
          perimeter: firstParcel.parcel.perimeter
        };
        // Also include all selected parcels as array
        requestBody.selectedParcels = selectedParcels.map(p => ({
          id: p.parcel.id,
          egrid: p.parcel.egrid,
          number: p.parcel.number,
          name: p.parcel.name,
          identnd: p.parcel.identnd,
          canton: p.parcel.canton,
          municipality_code: p.parcel.municipality_code,
          municipality_name: p.parcel.municipality_name,
          address: p.parcel.address,
          area_m2: p.parcel.area_m2,
          centroid: p.parcel.centroid,
          geoportal_url: p.parcel.geoportal_url,
          realestate_type: p.parcel.realestate_type,
          geometry_geojson: p.map_view?.geometry_geojson,
          perimeter: p.parcel.perimeter
        }));
      }

      const response = await api.post('/api/realestate/command', requestBody);

      const data: CommandResponse = response.data;

      // Format response as assistant message
      let responseMessage = '';
      if (data.success) {
        if (data.result) {
          if (typeof data.result === 'object') {
            responseMessage = `**Intent:** ${data.intent || 'Unknown'}\n**Entity:** ${data.entity || 'N/A'}\n\n**Result:**\n\`\`\`json\n${JSON.stringify(data.result, null, 2)}\n\`\`\``;
          } else {
            responseMessage = `**Intent:** ${data.intent || 'Unknown'}\n**Entity:** ${data.entity || 'N/A'}\n\n**Result:** ${data.result}`;
          }
        } else {
          responseMessage = `Command executed successfully.\n**Intent:** ${data.intent || 'Unknown'}\n**Entity:** ${data.entity || 'N/A'}`;
        }
      } else {
        responseMessage = `Error: ${data.error || 'Unknown error'}`;
      }

      const assistantMessage = {
        id: `assistant-${Date.now()}`,
        role: 'assistant',
        message: responseMessage,
        timestamp: Date.now()
      };
      setCommandResults((prev) => [...prev, assistantMessage]);

      // If a project was created and there are selected parcels, automatically add them
      if (data.success && data.intent === 'CREATE' && data.entity === 'Projekt' && selectedParcels.length > 0) {
        try {
          // Extract projekt from result
          const projektResult = data.result?.result || data.result;
          if (projektResult?.id) {
            // Set as current projekt
            setCurrentProjekt(projektResult);
            
            // Add all selected parcels to the newly created project via direct API call
            let addedCount = 0;
            for (const selectedParcel of selectedParcels) {
              try {
                const addParcelRequestBody: any = {
                  parcelId: selectedParcel.parcel.id,
                  parcelData: {
                    id: selectedParcel.parcel.id,
                    egrid: selectedParcel.parcel.egrid,
                    number: selectedParcel.parcel.number,
                    name: selectedParcel.parcel.name,
                    identnd: selectedParcel.parcel.identnd,
                    canton: selectedParcel.parcel.canton,
                    municipality_code: selectedParcel.parcel.municipality_code,
                    municipality_name: selectedParcel.parcel.municipality_name,
                    address: selectedParcel.parcel.address,
                    area_m2: selectedParcel.parcel.area_m2,
                    centroid: selectedParcel.parcel.centroid,
                    geoportal_url: selectedParcel.parcel.geoportal_url,
                    realestate_type: selectedParcel.parcel.realestate_type,
                    geometry_geojson: selectedParcel.map_view?.geometry_geojson,
                    perimeter: selectedParcel.parcel.perimeter
                  }
                };

                const addResponse = await api.post(
                  `/api/realestate/projekt/${projektResult.id}/add-parcel`,
                  addParcelRequestBody
                );
                const addResult: AddParcelResponse = addResponse.data;

                // Update current projekt with the updated version that includes the parcel
                setCurrentProjekt(addResult.projekt);
                addedCount++;
              } catch (addError: any) {
                console.error(`Failed to add parcel ${selectedParcel.parcel.id} to project:`, addError);
              }
            }

            // Update the assistant message to indicate parcels were added
            const parcelText = addedCount === 1 ? 'Parzelle' : 'Parzellen';
            const updateMessage = {
              ...assistantMessage,
              id: `assistant-update-${Date.now()}`,
              message: `${responseMessage}\n\n✅ ${addedCount} ${parcelText} ${addedCount === 1 ? 'wurde' : 'wurden'} automatisch zum Projekt hinzugefügt.`
            };
            setCommandResults((prev) => {
              const updated = [...prev];
              const lastIndex = updated.length - 1;
              if (updated[lastIndex]?.id === assistantMessage.id) {
                updated[lastIndex] = updateMessage;
              }
              return updated;
            });
          }
        } catch (addError: any) {
          // Log error but don't fail the command
          console.error('Failed to automatically add parcel to project:', addError);
          const errorMessage = addError.response?.data?.detail || addError.message || 'Unbekannter Fehler';
          const errorUpdate = {
            id: `assistant-error-${Date.now()}`,
            role: 'assistant',
            message: `⚠️ Projekt wurde erstellt, aber Parzelle konnte nicht automatisch hinzugefügt werden: ${errorMessage}`,
            timestamp: Date.now()
          };
          setCommandResults((prev) => [...prev, errorUpdate]);
        }
      }

      // If a parcel was created and there are selected parcels, automatically populate it with the first selected parcel data
      if (data.success && data.intent === 'CREATE' && data.entity === 'Parzelle' && selectedParcels.length > 0) {
        const selectedParcel = selectedParcels[0]; // Use first selected parcel
        try {
          // Extract parzelle from result
          const parzelleResult = data.result?.result || data.result;
          if (parzelleResult?.id) {
            // Update the newly created parcel with data from the selected parcel
            const updateParcelRequestBody: any = {
              // Map selected parcel data to parzelle fields
              egrid: selectedParcel.parcel.egrid,
              number: selectedParcel.parcel.number,
              name: selectedParcel.parcel.name,
              identnd: selectedParcel.parcel.identnd,
              canton: selectedParcel.parcel.canton,
              municipality_code: selectedParcel.parcel.municipality_code,
              municipality_name: selectedParcel.parcel.municipality_name,
              address: selectedParcel.parcel.address,
              strasseNr: selectedParcel.parcel.address,
              area_m2: selectedParcel.parcel.area_m2,
              centroid: selectedParcel.parcel.centroid,
              geoportal_url: selectedParcel.parcel.geoportal_url,
              realestate_type: selectedParcel.parcel.realestate_type,
              // Include geometry data
              geometry_geojson: selectedParcel.map_view?.geometry_geojson,
              perimeter: selectedParcel.parcel.perimeter
            };

            // Try to update the parcel via PUT request
            try {
              await api.put(
                `/api/realestate/parzelle/${parzelleResult.id}`,
                updateParcelRequestBody
              );

              // Update the assistant message to indicate parcel was populated
              const updateMessage = {
                ...assistantMessage,
                id: `assistant-update-${Date.now()}`,
                message: `${responseMessage}\n\n✅ Parzelle wurde automatisch mit Daten der Kartenauswahl befüllt.`
              };
              setCommandResults((prev) => {
                const updated = [...prev];
                const lastIndex = updated.length - 1;
                if (updated[lastIndex]?.id === assistantMessage.id) {
                  updated[lastIndex] = updateMessage;
                }
                return updated;
              });
            } catch (putError: any) {
              // If PUT doesn't work, try PATCH
              try {
                await api.patch(
                  `/api/realestate/parzelle/${parzelleResult.id}`,
                  updateParcelRequestBody
                );

                const updateMessage = {
                  ...assistantMessage,
                  id: `assistant-update-${Date.now()}`,
                  message: `${responseMessage}\n\n✅ Parzelle wurde automatisch mit Daten der Kartenauswahl befüllt.`
                };
                setCommandResults((prev) => {
                  const updated = [...prev];
                  const lastIndex = updated.length - 1;
                  if (updated[lastIndex]?.id === assistantMessage.id) {
                    updated[lastIndex] = updateMessage;
                  }
                  return updated;
                });
              } catch (patchError: any) {
                // If both PUT and PATCH fail, log but don't fail the command
                console.error('Failed to update parcel with selected parcel data:', patchError);
                const errorMessage = patchError.response?.data?.detail || patchError.message || 'Unbekannter Fehler';
                const errorUpdate = {
                  id: `assistant-error-${Date.now()}`,
                  role: 'assistant',
                  message: `⚠️ Parzelle wurde erstellt, aber konnte nicht automatisch mit Kartenauswahl-Daten befüllt werden: ${errorMessage}`,
                  timestamp: Date.now()
                };
                setCommandResults((prev) => [...prev, errorUpdate]);
              }
            }
          }
        } catch (updateError: any) {
          // Log error but don't fail the command
          console.error('Failed to automatically populate parcel with selected parcel data:', updateError);
          const errorMessage = updateError.response?.data?.detail || updateError.message || 'Unbekannter Fehler';
          const errorUpdate = {
            id: `assistant-error-${Date.now()}`,
            role: 'assistant',
            message: `⚠️ Parzelle wurde erstellt, aber konnte nicht automatisch mit Kartenauswahl-Daten befüllt werden: ${errorMessage}`,
            timestamp: Date.now()
          };
          setCommandResults((prev) => [...prev, errorUpdate]);
        }
      }

      // Clear input on success
      setCommandInput('');

      return { success: true, data };
    } catch (err: any) {
      const errorMessage = err.response?.data?.detail || err.message || 'Failed to send command';
      setCommandError(errorMessage);

      // Add error message
      const errorMsg = {
        id: `error-${Date.now()}`,
        role: 'assistant',
        message: `**Error:** ${errorMessage}`,
        timestamp: Date.now()
      };
      setCommandResults((prev) => [...prev, errorMsg]);

      return { success: false, error: errorMessage };
    } finally {
      setIsProcessingCommand(false);
    }
  }, [selectedParcels]);

  /**
   * Create a new project
   */
  const createProjekt = useCallback(
    async (data: {
      label: string;
      statusProzess?: string;
      location?: string;
      parcelIds?: string[];
    }) => {
      setIsCreatingProjekt(true);
      setProjektError(null);

      try {
        const requestBody: any = {
          label: data.label
        };

        if (data.statusProzess) {
          requestBody.statusProzess = data.statusProzess;
        }

        if (data.location) {
          requestBody.location = data.location;
        }

        if (data.parcelIds && data.parcelIds.length > 0) {
          requestBody.parcelIds = data.parcelIds;
        }

        const response = await api.post('/api/realestate/projekt/create', requestBody);
        const result: CreateProjektResponse = response.data;

        setCurrentProjekt(result.projekt);
        return { success: true, data: result };
      } catch (err: any) {
        const errorMessage =
          err.response?.data?.detail || err.message || 'Fehler beim Erstellen des Projekts';
        setProjektError(errorMessage);
        return { success: false, error: errorMessage };
      } finally {
        setIsCreatingProjekt(false);
      }
    },
    []
  );

  /**
   * Add a parcel to an existing project
   */
  const addParcelToProjekt = useCallback(
    async (
      projektId: string,
      data: {
        parcelId?: string;
        location?: string;
        parcelData?: Record<string, any>;
      }
    ) => {
      if (!currentProjekt || currentProjekt.id !== projektId) {
        setProjektError('Projekt nicht gefunden');
        return { success: false, error: 'Projekt nicht gefunden' };
      }

      setIsAddingParcel(true);
      setProjektError(null);

      try {
        const requestBody: any = {};

        if (data.parcelId) {
          requestBody.parcelId = data.parcelId;
        } else if (data.location) {
          requestBody.location = data.location;
        } else if (data.parcelData) {
          requestBody.parcelData = data.parcelData;
        } else {
          throw new Error('Bitte geben Sie parcelId, location oder parcelData an');
        }

        const response = await api.post(
          `/api/realestate/projekt/${projektId}/add-parcel`,
          requestBody
        );
        const result: AddParcelResponse = response.data;

        setCurrentProjekt(result.projekt);
        return { success: true, data: result };
      } catch (err: any) {
        const errorMessage =
          err.response?.data?.detail || err.message || 'Fehler beim Hinzufügen der Parzelle';
        setProjektError(errorMessage);
        return { success: false, error: errorMessage };
      } finally {
        setIsAddingParcel(false);
      }
    },
    [currentProjekt]
  );

  // Build location string from separate fields
  const buildLocationString = useCallback(() => {
    const parts = [kanton, gemeinde, adresse].filter(Boolean);
    return parts.join(', ');
  }, [kanton, gemeinde, adresse]);

  return {
    // Location input - separate fields
    kanton,
    setKanton,
    gemeinde,
    setGemeinde,
    adresse,
    setAdresse,
    buildLocationString,
    // Legacy locationInput for backward compatibility
    locationInput,
    setLocationInput,
    useCurrentLocation,
    isGettingLocation,
    locationError,

    // Parcel search
    selectedParcels,
    searchParcel,
    isSearchingParcel,
    parcelSearchError,
    removeParcel,
    clearSelectedParcels,
    isParcelSelected,

    // Map view
    mapCenter,
    mapZoomBounds,
    parcelGeometries,
    handleMapClick,
    handleParcelClick,

    // Command processing
    commandInput,
    setCommandInput,
    processCommand,
    isProcessingCommand,
    commandResults,
    commandError,

    // Project management
    currentProjekt,
    createProjekt,
    isCreatingProjekt,
    addParcelToProjekt,
    isAddingParcel,
    projektError,

    // Panel state
    isPanelOpen,
    setIsPanelOpen
  };
}
