import React, { useState, useEffect, useContext } from 'react';
import { useLocation, useParams, useNavigate } from 'react-router-dom';
import {
  Container,
  Typography,
  CircularProgress,
  Grid,
  Alert,
  Divider,
  Card,
  CardContent,
  Button,
  private_excludeVariablesFromRoot,
} from '@mui/material';
import { PropertiesAPI, SavedPropertiesAPI } from 'types';
import PropertyDetailCard from 'components/sections/dashboard/Home/Property/PropertyDetailCard';
import SaleTaxHistoryCard from 'components/sections/dashboard/Home/Property/SaleTaxHistoryCard';
import WalkScoreCard from 'components/sections/dashboard/Home/Property/WalkScoreCard';
import OpenHouseCard from 'components/sections/dashboard/Home/Profile/OpenHouseCard';
import PropertyStatusCard from 'components/sections/dashboard/Home/Property/PropertyStatusCard';
import EstimatedMonthlyCostCard from 'components/sections/dashboard/Home/Profile/EstimatedMonthlyCostCard';
import OfferSubmissionCard from 'components/sections/dashboard/Home/Profile/OfferSubmissionCard';
import axios, { AxiosResponse } from 'axios';
import { axiosInstance } from '../../axiosApi';
import SchoolCard from 'components/sections/dashboard/Home/Property/SchoolCard';
import { AccountContext } from 'contexts/AccountContext';
import SellerInformationCard from 'components/sections/dashboard/Home/Property/SellerInformationCard';

const PropertyDetailPage: React.FC = () => {
  // In a real app, you'd get propertyId from URL params or a global state
  const { account, accountLoading } = useContext(AccountContext);
  const { propertyId } = useParams<{ propertyId: string }>();
  const location = useLocation();
  const navigate = useNavigate();
  const searchParams = new URLSearchParams(location.search);
  const isSearch = searchParams.get('search') === '1';

  const [property, setProperty] = useState<PropertiesAPI | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
  const [savedProperty, setSavedProperty] = useState<SavedPropertiesAPI | null>(null);

  useEffect(() => {
    // Simulate API call
    const getProperty = async () => {
      try {
        setLoading(true);
        setError(null);
        const url = isSearch ? `/properties/${propertyId}/?search=1` : `/properties/${propertyId}/`;
        const { data }: AxiosResponse<PropertiesAPI> = await axiosInstance.get(url);
        if (isSearch) {
          // kick the view count
          await axiosInstance.post(`/properties/${propertyId}/increment_view_count/?search=1`);
        }
        if (data !== undefined) {
          setProperty(data);
        }
      } catch {
        setError('Property not found.');
      } finally {
        setLoading(false);
      }
    };
    const getSavedProperties = async () => {
      if (account) {
        // only fetch if logged in
        try {
          const { data }: AxiosResponse<SavedPropertiesAPI[]> =
            await axiosInstance.get('/saved-properties/');
          setSavedProperty(data.find((item) => item.property.toString() === propertyId));
        } catch (error) {}
      }
    };
    getProperty();
    getSavedProperties();
  }, [propertyId, account, isSearch]);

  const handleSaveProperty = (updatedProperty: PropertiesAPI) => {
    // In a real app, this would be an API call to update the property
    console.log('Saving property:', updatedProperty);
    setProperty(updatedProperty);
    setMessage({ type: 'success', text: 'Property details updated successfully!' });
    setTimeout(() => setMessage(null), 3000);
  };

  const onStatusChange = async (value: string) => {
    if (property) {
      try {
        await axiosInstance.patch<SavedPropertiesAPI>(`/properties/${property.id}/`, {
          property_status: value,
        });
        setProperty((prev) => (prev ? { ...prev, property_status: value } : null));
        setMessage({ type: 'success', text: `Your listing is now ${value}` });
      } catch (error) {
        setMessage({
          type: 'error',
          text: 'There was an error saving your selection. Please try again',
        });
        setTimeout(() => setMessage(null), 3000);
      }
    } else {
      setMessage({
        type: 'error',
        text: 'There was an error saving your selection. Please refresh the page and try again',
      });
      setTimeout(() => setMessage(null), 3000);
    }
  };

  const onSavedPropertySave = async () => {
    if (property && account) {
      try {
        if (savedProperty) {
          await axiosInstance.delete<SavedPropertiesAPI>(`/saved-properties/${savedProperty.id}/`);
          setSavedProperty(null);
          setProperty((prev) =>
            prev
              ? {
                  ...prev,
                  saves: prev.saves - 1,
                }
              : null,
          );
        } else {
          const { data } = await axiosInstance.post<SavedPropertiesAPI>(`/saved-properties/`, {
            property: property.id,
            user: account.id,
          });
          setSavedProperty(data);
          setProperty((prev) =>
            prev
              ? {
                  ...prev,
                  saves: prev.saves + 1,
                }
              : null,
          );
        }
      } catch (error) {
        setMessage({
          type: 'error',
          text: 'There was an error saving your selection. Please try again.',
        });
        setTimeout(() => setMessage(null), 3000);
      }
    } else {
      navigate('/login');
    }
  };

  const handleDeleteProperty = (propertyId: number) => {
    console.log('handle delete. IMPLEMENT ME', propertyId);
  };

  const handleSendMessage = () => {
    if (property && property.owner && property.owner.user) {
      navigate(`/messages?recipient=${property.owner.user.id}`);
    }
  };

  const handleOfferSubmit = async (
    offerAmount: number,
    closing_days: number,
    contingencies: string,
  ): Promise<{ status: number; message?: string }> => {
    try {
      const response = await axiosInstance.post('/documents/upload/', {
        document_type: 'offer',
        property: propertyId,
        offer_price: offerAmount,
        closing_days: closing_days,
        contingencies: contingencies,
      });
      return { status: response.status };
    } catch (error) {
      if (axios.isAxiosError(error) && error.response) {
        return {
          status: error.response.status,
          message: error.response.data?.detail || 'Failed to submit offer.',
        };
      }
      return {
        status: 500,
        message: 'An unexpected error occurred.',
      };
    }
  };

  if (loading || accountLoading) {
    return (
      <Container maxWidth="lg" sx={{ mt: 4, mb: 4, textAlign: 'center' }}>
        <CircularProgress />
        <Typography>Loading property details...</Typography>
      </Container>
    );
  }

  if (error) {
    return (
      <Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
        <Alert severity="error">{error}</Alert>
      </Container>
    );
  }

  if (!property) {
    return (
      <Container maxWidth="lg" sx={{ mt: 4, mb: 4 }}>
        <Alert severity="info">No property data available.</Alert>
      </Container>
    );
  }

  // Determine if the current user is the owner of this property
  const isOwnerOfProperty = account ? account.id === property.owner.user.id : false;
  const priceForAnalysis = property.listed_price ? property.listed_price : property.market_value;

  const sellerDisclosureExists = property.documents
    ? property.documents.some(
        (doc) => doc.document_type === 'seller_disclosure' && doc.sub_document,
      )
    : false;

  const disclosureDocument = property.documents?.find(
    (doc) => doc.document_type === 'seller_disclosure',
  );
  const sellerDisclosureData = disclosureDocument?.sub_document as any; // Using 'any' to avoid type conflicts for now.

  const existingOffer = property.documents
    ? property.documents.find((doc) => doc.document_type === 'offer_letter')
    : undefined;

  // TODO fix this
  console.log(property);
  console.log(property.documents);
  console.log(existingOffer);

  return (
    <Container maxWidth="xl" sx={{ mt: 4, mb: 4 }}>
      {message && (
        <Alert severity={message.type} sx={{ mb: 2 }}>
          {message.text}
        </Alert>
      )}

      <Grid container spacing={3}>
        {/* Main Property Details */}
        <Grid size={{ xs: 12, md: 8 }}>
          <PropertyDetailCard
            property={property}
            isPublicPage={true}
            onSave={handleSaveProperty}
            isOwnerView={isOwnerOfProperty}
            onDelete={() => handleDeleteProperty(property.id)}
          />
        </Grid>

        <Grid size={{ xs: 12, md: 4 }}>
          <Grid container spacing={3}>
            <Grid size={{ xs: 12 }}>
              <PropertyStatusCard
                property={property}
                isOwner={isOwnerOfProperty}
                onStatusChange={onStatusChange}
                onSavedPropertySave={onSavedPropertySave}
                savedProperty={savedProperty}
                sellerDisclosureExists={sellerDisclosureExists}
              />
            </Grid>
            <Grid size={{ xs: 12 }}>
              <EstimatedMonthlyCostCard price={parseFloat(priceForAnalysis)} />
            </Grid>
            {!isOwnerOfProperty && (
              <>
                <Grid size={{ xs: 12 }}>
                  <OfferSubmissionCard
                    onOfferSubmit={handleOfferSubmit}
                    listingStatus={property.property_status}
                    listingPrice={priceForAnalysis}
                    existingOffer={existingOffer ? { document_id: existingOffer.id } : undefined}
                  />
                </Grid>
                <Grid size={{ xs: 12 }}>
                  <SellerInformationCard
                    sellerDisclosureExists={sellerDisclosureExists}
                    onSendMessage={handleSendMessage}
                    disclosureData={sellerDisclosureData}
                    property={property}
                  />
                </Grid>
              </>
            )}

            <Grid size={{ xs: 12 }}>
              <OpenHouseCard openHouses={property.open_houses} />
            </Grid>
          </Grid>
        </Grid>

        {/* Additional Information */}
        <Grid size={{ xs: 12 }}>
          <Divider sx={{ my: 2 }} />
        </Grid>

        <Grid size={{ xs: 12, md: 4 }}>
          <SaleTaxHistoryCard saleHistory={property.sale_info} taxInfo={property.tax_info} />
        </Grid>
        <Grid size={{ xs: 12, md: 4 }}>
          <WalkScoreCard walkScore={property.walk_score} />
        </Grid>
        <Grid size={{ xs: 12, md: 4 }}>
          {property.schools && <SchoolCard schools={property.schools} />}
        </Grid>
      </Grid>
    </Container>
  );
};

export default PropertyDetailPage;
