import React, { useState, useEffect } from 'react';
import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  TextField,
  Grid,
  Autocomplete,
  CircularProgress,
  Box,
  Alert,
} from '@mui/material';
import { axiosInstance, axiosRealEstateApi } from '../../../../../axiosApi';

import MapComponent from '../../../../base/MapComponent';
import {
  AutocompleteDataResponseAPI,
  AutocompleteResponseAPI,
  PropertiesAPI,
  PropertResponseDataAPI,
  PropertyResponseAPI,
  SaleHistoryAPI,
  SchoolAPI,
} from 'types';
import { test_property_search } from 'data/mock_property_search';
import { extractLatLon } from 'utils';
import { test_autocomplete } from 'data/mock_autocomplete_results';

interface AddPropertyDialogProps {
  open: boolean;
  onClose: () => void;
  onAddProperty: (
    newProperty: Omit<PropertiesAPI, 'id' | 'owner' | 'created_at' | 'last_updated'>,
  ) => void;
}

export interface PlacePrediction {
  description: string;
  place_id: string;
}

const AddPropertyDialog: React.FC<AddPropertyDialogProps> = ({ open, onClose, onAddProperty }) => {
  const initalValues: Omit<PropertiesAPI, 'id' | 'owner' | 'created_at' | 'last_updated'> = {
    address: '',
    street: '',
    city: '',
    state: '',
    zip_code: '',
    market_value: '',
    loan_amount: '',
    loan_term: 0,
    loan_start_date: '',
    pictures: [],
    description: '',
    sq_ft: 0,
    features: [],
    num_bedrooms: 0,
    num_bathrooms: 0,
    latitude: undefined,
    longitude: undefined,
    realestate_api_id: 0,
    views: 0,
    saves: 0,
    property_status: 'off_market',
    schools: [],
  };
  const [newProperty, setNewProperty] = useState<
    Omit<PropertiesAPI, 'id' | 'owner' | 'created_at' | 'last_updated'>
  >({
    ...initalValues,
  });
  const [autocompleteOptions, setAutocompleteOptions] = useState<PlacePrediction[]>([]);
  const [autocompleteLoading, setAutocompleteLoading] = useState(false);
  const [formErrors, setFormErrors] = useState<{ [key: string]: string }>({});
  const [selectedPlace, setSelectedPlace] = useState<PlacePrediction | null>(null);

  // Initialize Google Maps Places Service (requires Google Maps API key loaded globally)
  // This is a simplified approach. For a more robust solution, use @vis.gl/react-google-maps useMapsLibrary hook
  useEffect(() => {
    if (!window.google || !window.google.maps || !window.google.maps.places) {
      console.warn('Google Maps Places API not loaded. Autocomplete will not function.');
      // You might want to handle this by displaying a message or disabling autocomplete
    }
  }, []);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setNewProperty((prev) => ({ ...prev, [name]: value }));
    if (formErrors[name]) {
      setFormErrors((prev) => {
        const newErrors = { ...prev };
        delete newErrors[name];
        return newErrors;
      });
    }
  };

  const handleAddressAutocompleteInputChange = async (
    event: React.SyntheticEvent,
    value: string,
  ) => {
    const test: boolean = !import.meta.env.USE_LIVE_DATA;
    let data: AutocompleteDataResponseAPI[] = [];
    if (value.length > 2) {
      if (test) {
        data = test_autocomplete.data.filter((item) => item.address.includes(value));
        // filter the data here
      } else {
        const { data } = await axiosRealEstateApi.post<AutocompleteDataResponseAPI[]>(
          'AutoComplete',
          {
            search: value,
          },
        );
      }
      setAutocompleteOptions(
        data.map((item) => ({
          description: item.address,
          place_id: item.id,
        })),
      );
    } else {
      console.log('we need more characters');
    }

    setNewProperty((prev) => ({ ...prev, address: value }));
    // if (value.length > 2 && window.google && window.google.maps && window.google.maps.places) {
    //     setAutocompleteLoading(true);
    //     const service = new window.google.maps.places.AutocompleteService();
    //     service.getPlacePredictions({ input: value }, (predictions, status) => {
    //         if (status === window.google.maps.places.PlacesServiceStatus.OK && predictions) {
    //             setAutocompleteOptions(predictions.map(p => ({ description: p.description, place_id: p.place_id })));
    //         } else {
    //             setAutocompleteOptions([]);
    //         }
    //         setAutocompleteLoading(false);
    //     });
    // } else {
    //     setAutocompleteOptions([]);
    // }
  };

  const handleAddressAutocompleteChange = async (
    event: React.SyntheticEvent,
    value: PlacePrediction | null,
  ) => {
    setSelectedPlace(value);
    console.log('here we go', value);
    if (value) {
      console.log('find the test data');
      const test: boolean = true;
      if (test) {
        const parts: string[] =
          test_property_search.data.currentMortgages[0].recordingDate.split('T');

        // get the features

        // get the schools

        const schools: Omit<SchoolAPI, 'id' | 'created_at' | 'last_updated'>[] =
          test_property_search.data.schools.map((item) => {
            const coordinates = extractLatLon(item.location);
            return {
              city: item.city,
              state: item.state,
              zip_code: item.zip,
              latitude: coordinates?.latitude,
              longitude: coordinates?.longitude,
              school_type: item.type,
              enrollment: item.enrollment,
              grades: item.grades,
              name: item.name,
              parent_rating: item.parentRating,
              rating: item.rating,
            };
          });
        console.log(schools);

        // get the sale history
        const sale_history: Omit<SaleHistoryAPI, 'id' | 'created_at' | 'last_updated'>[] =
          test_property_search.data.saleHistory.map((item) => {
            return {
              seq_no: item.seqNo,
              sale_date: item.saleDate,
              sale_amount: item.saleAmount,
            };
          });

        setNewProperty({
          address: test_property_search.data.propertyInfo.address.address,
          street: test_property_search.data.ownerInfo.mailAddress.address,
          city: test_property_search.data.propertyInfo.address.city,
          state: test_property_search.data.propertyInfo.address.state,
          zip_code: test_property_search.data.propertyInfo.address.zip,
          latitude: test_property_search.data.propertyInfo.latitude,
          longitude: test_property_search.data.propertyInfo.longitude,
          market_value: test_property_search.data.estimatedValue.toString(),
          loan_amount: test_property_search.data.currentMortgages[0].amount.toString(),
          loan_term: test_property_search.data.currentMortgages[0].term,
          loan_start_date: parts[0],
          description: '',
          features: [],
          pictures: [],
          num_bedrooms: test_property_search.data.propertyInfo.bedrooms,
          num_bathrooms: test_property_search.data.propertyInfo.bathrooms,
          sq_ft: test_property_search.data.propertyInfo.buildingSquareFeet,
          realestate_api_id: test_property_search.data.id,
          views: 0,
          saves: 0,
          property_status: 'off_market',
          schools: schools,
          tax_info: {
            assessed_value: test_property_search.data.taxInfo.assessedValue,
            assessment_year: test_property_search.data.taxInfo.assessmentYear,
            tax_amount: Number(test_property_search.data.taxInfo.taxAmount),
            year: test_property_search.data.taxInfo.year,
          },
          sale_info: sale_history,
        });
      }
    }
  };

  // Simple file upload simulation (you'd replace this with actual file handling and storage)
  const handlePictureUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      const filesArray = Array.from(e.target.files);
      // In a real app, you'd upload these files and get URLs back
      const imageUrls = filesArray.map((file) => URL.createObjectURL(file)); // For display purposes
      setNewProperty((prev) => ({ ...prev, pictures: [...prev.pictures, ...imageUrls] }));
    }
  };

  const validateForm = () => {
    const errors: { [key: string]: string } = {};
    if (!newProperty.address.trim()) {
      errors.address = 'Address is required.';
    }
    if (!newProperty.city.trim()) {
      errors.city = 'City is required.';
    }
    if (!newProperty.state.trim()) {
      errors.state = 'State is required.';
    }
    if (!newProperty.zip_code.trim()) {
      errors.zip_code = 'Zip code is required.';
    }
    if (newProperty.sq_ft <= 0) {
      errors.sq_ft = 'Square footage must be greater than 0.';
    }
    if (newProperty.num_bedrooms < 0) {
      errors.num_bedrooms = 'Number of bedrooms cannot be negative.';
    }
    if (newProperty.num_bathrooms < 0) {
      errors.num_bathrooms = 'Number of bathrooms cannot be negative.';
    }
    setFormErrors(errors);
    return Object.keys(errors).length === 0;
  };

  const handleAdd = () => {
    if (validateForm()) {
      onAddProperty(newProperty);
      onClose();
      // Reset form
      setNewProperty(initalValues);
      setAutocompleteOptions([]);
      setSelectedPlace(null);
      setFormErrors({});
    }
  };

  const handleCloseAndReset = () => {
    onClose();
    setNewProperty(initalValues);
    setAutocompleteOptions([]);
    setSelectedPlace(null);
    setFormErrors({});
  };

  return (
    <Dialog open={open} onClose={handleCloseAndReset} fullWidth maxWidth="md">
      <DialogTitle>Add New Property</DialogTitle>
      <DialogContent dividers>
        <Grid container spacing={2}>
          <Grid size={{ xs: 12 }}>
            <Autocomplete
              options={autocompleteOptions}
              getOptionLabel={(option) => option.description}
              inputValue={newProperty.address}
              noOptionsText={'Type at least 3 characters'}
              onInputChange={handleAddressAutocompleteInputChange}
              onChange={handleAddressAutocompleteChange}
              isOptionEqualToValue={(option, value) => option.place_id === value.place_id}
              loading={autocompleteLoading}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="Address"
                  name="address"
                  fullWidth
                  required
                  error={!!formErrors.address}
                  helperText={formErrors.address}
                  InputProps={{
                    ...params.InputProps,
                    endAdornment: (
                      <>
                        {autocompleteLoading ? (
                          <CircularProgress color="inherit" size={20} />
                        ) : null}
                        {params.InputProps.endAdornment}
                      </>
                    ),
                  }}
                />
              )}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 6 }}>
            <TextField
              fullWidth
              label="City"
              name="city"
              value={newProperty.city}
              onChange={handleInputChange}
              required
              error={!!formErrors.city}
              helperText={formErrors.city}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 6 }}>
            <TextField
              fullWidth
              label="State"
              name="state"
              value={newProperty.state}
              onChange={handleInputChange}
              required
              error={!!formErrors.state}
              helperText={formErrors.state}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 6 }}>
            <TextField
              fullWidth
              label="Zip Code"
              name="zip_code"
              value={newProperty.zip_code}
              onChange={handleInputChange}
              required
              error={!!formErrors.zip_code}
              helperText={formErrors.zip_code}
            />
          </Grid>
          <Grid size={{ xs: 12 }}>
            <TextField
              fullWidth
              label="Description"
              name="description"
              multiline
              rows={3}
              value={newProperty.description}
              onChange={handleInputChange}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 4 }}>
            <TextField
              fullWidth
              label="Square Footage"
              name="sq_ft"
              type="number"
              value={newProperty.sq_ft || ''}
              onChange={handleInputChange}
              error={!!formErrors.sq_ft}
              helperText={formErrors.sq_ft}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 4 }}>
            <TextField
              fullWidth
              label="# Bedrooms"
              name="num_bedrooms"
              type="number"
              value={newProperty.num_bedrooms || ''}
              onChange={handleInputChange}
              error={!!formErrors.num_bedrooms}
              helperText={formErrors.num_bedrooms}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 4 }}>
            <TextField
              fullWidth
              label="# Bathrooms"
              name="num_bathrooms"
              type="number"
              value={newProperty.num_bathrooms || ''}
              onChange={handleInputChange}
              error={!!formErrors.num_bathrooms}
              helperText={formErrors.num_bathrooms}
            />
          </Grid>
          <Grid size={{ xs: 12 }}>
            <TextField
              fullWidth
              label="Features (comma-separated)"
              name="features"
              value={newProperty.features.join(', ')}
              onChange={(e) =>
                setNewProperty((prev) => ({
                  ...prev,
                  features: e.target.value.split(',').map((f) => f.trim()),
                }))
              }
            />
          </Grid>
          <Grid size={{ xs: 12 }}>
            <TextField
              fullWidth
              label="Market Value"
              name="market_value"
              value={newProperty.market_value}
              onChange={handleInputChange}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 6 }}>
            <TextField
              fullWidth
              label="Loan Amount"
              name="loan_amount"
              value={newProperty.loan_amount}
              onChange={handleInputChange}
            />
          </Grid>
          <Grid size={{ xs: 12, sm: 6 }}>
            <TextField
              fullWidth
              label="Loan Term (years)"
              name="loan_term"
              type="number"
              value={newProperty.loan_term || ''}
              onChange={handleInputChange}
            />
          </Grid>
          <Grid size={{ xs: 12 }}>
            <TextField
              fullWidth
              label="Loan Start Date"
              name="loan_start_date"
              type="date"
              InputLabelProps={{ shrink: true }}
              value={newProperty.loan_start_date}
              onChange={handleInputChange}
            />
          </Grid>
          <Grid size={{ xs: 12 }}>
            <Button variant="contained" component="label">
              Upload Pictures
              <input type="file" hidden multiple accept="image/*" onChange={handlePictureUpload} />
            </Button>
            <Box sx={{ mt: 1, display: 'flex', flexWrap: 'wrap', gap: 1 }}>
              {newProperty.pictures.map((url, index) => (
                <img
                  key={index}
                  src={url}
                  alt={`Uploaded ${index}`}
                  style={{ width: 100, height: 100, objectFit: 'cover', borderRadius: 4 }}
                />
              ))}
            </Box>
          </Grid>
          {newProperty.latitude && newProperty.longitude && (
            <Grid size={{ xs: 12 }}>
              <MapComponent
                lat={newProperty.latitude}
                lng={newProperty.longitude}
                address={newProperty.address}
              />
            </Grid>
          )}
        </Grid>
        {Object.keys(formErrors).length > 0 && (
          <Alert severity="error" sx={{ mt: 2 }}>
            Please correct the errors in the form.
          </Alert>
        )}
      </DialogContent>
      <DialogActions>
        <Button onClick={handleCloseAndReset}>Cancel</Button>
        <Button onClick={handleAdd} variant="contained" color="primary">
          Add Property
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export default AddPropertyDialog;
