import {
  Alert,
  Box,
  Button,
  Container,
  InputAdornment,
  Paper,
  Slider,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Typography,
} from '@mui/material';
import { ReactElement, useEffect, useMemo, useState } from 'react';

const HomeAffordability = (): ReactElement => {
  // State variables for affordability inputs
  const [annualIncome, setAnnualIncome] = useState<number | ''>('');
  const [downPayment, setDownPayment] = useState<number | ''>('');
  const [annualInterestRate, setAnnualInterestRate] = useState<number | ''>('');
  const [loanTermYears, setLoanTermYears] = useState<number | ''>(30); // Default to 30 years
  const [pmiRate, setPmiRate] = useState<number | ''>(0.5); // Default PMI rate as percentage
  const [propertyTaxRate, setPropertyTaxRate] = useState<number | ''>(1.2); // Default annual property tax rate as percentage
  const [homeInsuranceAnnual, setHomeInsuranceAnnual] = useState<number | ''>(1200); // Default annual home insurance
  const [otherMonthlyDebts, setOtherMonthlyDebts] = useState<number | ''>(0); // e.g., car payments, student loans
  const [maxDebtToIncomeRatio, setMaxDebtToIncomeRatio] = useState<number>(36); // Default DTI ratio as percentage

  // State variables for calculated results
  const [affordableHomePrice, setAffordableHomePrice] = useState<number>(0);
  const [estimatedMonthlyPayment, setEstimatedMonthlyPayment] = useState<number>(0);
  const [error, setError] = useState<string | null>(null);

  // Function to calculate home affordability
  const calculateAffordability = () => {
    // Reset error message and previous results
    setError(null);
    setAffordableHomePrice(0);
    setEstimatedMonthlyPayment(0);

    // Input validation
    if (
      annualIncome === '' ||
      annualInterestRate === '' ||
      loanTermYears === '' ||
      downPayment === ''
    ) {
      setError('Please fill in Annual Income, Down Payment, Annual Interest Rate, and Loan Term.');
      return;
    }
    if (Number(annualIncome) <= 0) {
      setError('Annual Income must be greater than 0.');
      return;
    }
    if (Number(downPayment) < 0) {
      setError('Down Payment cannot be negative.');
      return;
    }
    if (Number(annualInterestRate) < 0) {
      setError('Annual Interest Rate cannot be negative.');
      return;
    }
    if (Number(loanTermYears) <= 0) {
      setError('Loan Term must be greater than 0.');
      return;
    }
    if (Number(pmiRate) < 0 || Number(pmiRate) > 100) {
      setError('PMI Rate must be between 0 and 100.');
      return;
    }
    if (Number(propertyTaxRate) < 0 || Number(propertyTaxRate) > 100) {
      setError('Property Tax Rate must be between 0 and 100.');
      return;
    }
    if (Number(homeInsuranceAnnual) < 0) {
      setError('Annual Home Insurance cannot be negative.');
      return;
    }
    if (Number(otherMonthlyDebts) < 0) {
      setError('Other Monthly Debts cannot be negative.');
      return;
    }
    if (Number(maxDebtToIncomeRatio) <= 0 || Number(maxDebtToIncomeRatio) > 100) {
      setError('Max Debt-to-Income Ratio must be between 1 and 100.');
      return;
    }

    const income = Number(annualIncome);
    const dp = Number(downPayment);
    const annualRate = Number(annualInterestRate);
    const years = Number(loanTermYears);
    const pmiPercent = Number(pmiRate) / 100;
    const taxPercent = Number(propertyTaxRate) / 100;
    const insuranceAnnual = Number(homeInsuranceAnnual);
    const otherDebts = Number(otherMonthlyDebts);
    const maxDTI = Number(maxDebtToIncomeRatio) / 100;

    const monthlyIncome = income / 12;
    const maxMonthlyHousingPayment = monthlyIncome * maxDTI - otherDebts;

    if (maxMonthlyHousingPayment <= 0) {
      setError(
        'Your calculated maximum affordable monthly housing payment is zero or negative. Adjust inputs.',
      );
      return;
    }

    // Estimate affordable home price iteratively or using a more complex formula
    // For simplicity, we'll use an iterative approach or a target monthly payment
    // Let's assume the maximum monthly housing payment is the target for PITI.

    // PITI = Principal & Interest + Property Tax + Home Insurance + PMI
    // We need to find the Loan Amount (L) such that PITI is <= maxMonthlyHousingPayment
    // L = Home Price - Down Payment
    // P&I = L * (monthlyRate / (1 - (1 + monthlyRate)^-numPayments))
    // Property Tax (monthly) = Home Price * (annualTaxRate / 12)
    // Home Insurance (monthly) = Annual Insurance / 12
    // PMI (monthly) = L * (pmiRate / 12)  -- typically based on loan amount, not home price

    // This becomes a bit of an algebraic challenge to solve directly for Home Price.
    // A common approach is to solve for the maximum loan amount first, then add the down payment.

    const monthlyRate = annualRate / 100 / 12;
    const numberOfPayments = years * 12;

    // We need to estimate the maximum loan amount (L) that can be supported by maxMonthlyHousingPayment
    // Let's re-frame:
    // Max monthly payment for P&I + PMI = maxMonthlyHousingPayment - (Monthly Tax + Monthly Insurance)
    const monthlyInsurance = insuranceAnnual / 12;
    // We can't calculate monthly tax directly from home price yet, so we'll need to iterate or estimate.

    // Let's assume a starting guess for the affordable home price and refine.
    // Or, work backwards from the maximum monthly payment.

    // Option 1: Work backwards from max monthly housing payment to find max loan amount
    // M = P * [ i(1 + i)^n ] / [ (1 + i)^n – 1]
    // P = M / [ i(1 + i)^n ] / [ (1 + i)^n – 1]
    // Here, M is the portion of the maxMonthlyHousingPayment that can go towards P&I.
    // This is tricky because Tax and PMI depend on the home price/loan amount.

    // Let's use an iterative approach to find the affordable home price.
    let estimatedHomePrice = 0;
    let high = 5000000; // Upper bound for home price search
    let low = 10000; // Lower bound
    let iterations = 100; // Number of iterations for binary search

    while (iterations > 0 && high - low > 0.01) {
      // Iterate until precision is met
      const midPrice = (low + high) / 2;
      const loan = midPrice - dp;

      if (loan <= 0) {
        // If loan is not positive, this price is too low
        low = midPrice;
        iterations--;
        continue;
      }

      let estimatedPI = 0;
      if (monthlyRate === 0) {
        estimatedPI = loan / numberOfPayments;
      } else {
        estimatedPI = (loan * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -numberOfPayments));
      }

      const estimatedMonthlyTax = midPrice * (taxPercent / 12);
      const estimatedMonthlyPMI = loan * (pmiPercent / 12); // PMI usually on loan amount
      const currentEstimatedTotalMonthlyPayment =
        estimatedPI + estimatedMonthlyTax + monthlyInsurance + estimatedMonthlyPMI;

      if (currentEstimatedTotalMonthlyPayment <= maxMonthlyHousingPayment) {
        estimatedHomePrice = midPrice;
        low = midPrice; // Try for a higher price
      } else {
        high = midPrice; // Price is too high, reduce it
      }
      iterations--;
    }

    setAffordableHomePrice(estimatedHomePrice);

    // Calculate the estimated monthly payment for the affordable price
    const finalLoanAmount = estimatedHomePrice - dp;
    let finalPI = 0;
    if (monthlyRate === 0) {
      finalPI = finalLoanAmount / numberOfPayments;
    } else {
      finalPI =
        (finalLoanAmount * monthlyRate) / (1 - Math.pow(1 + monthlyRate, -numberOfPayments));
    }
    const finalMonthlyTax = estimatedHomePrice * (taxPercent / 12);
    const finalMonthlyPMI = finalLoanAmount * (pmiPercent / 12);
    const finalEstimatedMonthlyPayment =
      finalPI + finalMonthlyTax + monthlyInsurance + finalMonthlyPMI;
    setEstimatedMonthlyPayment(finalEstimatedMonthlyPayment);

    if (estimatedHomePrice === 0 && maxMonthlyHousingPayment > 0) {
      setError(
        'Could not find an affordable home price with the given inputs. Try adjusting values.',
      );
    }
  };

  return (
    <Container maxWidth="lg" sx={{ py: 4 }}>
      <Box sx={{ my: 4, textAlign: 'center' }}>
        <Typography variant="h4" component="h1" gutterBottom sx={{ color: 'background.paper' }}>
          Home Affordability Calculator
        </Typography>
        <Typography variant="subtitle1" color="text.secondary">
          Estimate how much home you can afford based on your income and debts.
        </Typography>
      </Box>

      <Paper elevation={3} sx={{ p: 4, mb: 4 }}>
        <Box
          component="form"
          sx={{
            display: 'grid',
            gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' }, // Two columns on medium screens and up
            gap: 3,
            mb: 3,
          }}
          noValidate
          autoComplete="off"
        >
          {/* Income and Down Payment */}
          <TextField
            label="Annual Income ($)"
            type="number"
            value={annualIncome}
            onChange={(e) => setAnnualIncome(e.target.value === '' ? '' : Number(e.target.value))}
            fullWidth
            variant="outlined"
            inputProps={{ min: 0 }}
            InputProps={{ startAdornment: <InputAdornment position="start">$</InputAdornment> }}
          />
          <TextField
            label="Down Payment ($)"
            type="number"
            value={downPayment}
            onChange={(e) => setDownPayment(e.target.value === '' ? '' : Number(e.target.value))}
            fullWidth
            variant="outlined"
            inputProps={{ min: 0 }}
            InputProps={{ startAdornment: <InputAdornment position="start">$</InputAdornment> }}
          />

          {/* Loan Details */}
          <TextField
            label="Annual Interest Rate (%)"
            type="number"
            value={annualInterestRate}
            onChange={(e) =>
              setAnnualInterestRate(e.target.value === '' ? '' : Number(e.target.value))
            }
            fullWidth
            variant="outlined"
            inputProps={{ min: 0 }}
            InputProps={{ endAdornment: <InputAdornment position="end">%</InputAdornment> }}
          />
          <TextField
            label="Loan Term (Years)"
            type="number"
            value={loanTermYears}
            onChange={(e) => setLoanTermYears(e.target.value === '' ? '' : Number(e.target.value))}
            fullWidth
            variant="outlined"
            inputProps={{ min: 0 }}
          />

          {/* Other Costs */}
          <TextField
            label="PMI Rate (Annual % of Loan Amount)"
            type="number"
            value={pmiRate}
            onChange={(e) => setPmiRate(e.target.value === '' ? '' : Number(e.target.value))}
            fullWidth
            variant="outlined"
            inputProps={{ min: 0, max: 100 }}
            InputProps={{ endAdornment: <InputAdornment position="end">%</InputAdornment> }}
          />
          <TextField
            label="Property Tax Rate (Annual % of Home Price)"
            type="number"
            value={propertyTaxRate}
            onChange={(e) =>
              setPropertyTaxRate(e.target.value === '' ? '' : Number(e.target.value))
            }
            fullWidth
            variant="outlined"
            inputProps={{ min: 0, max: 100 }}
            InputProps={{ endAdornment: <InputAdornment position="end">%</InputAdornment> }}
          />
          <TextField
            label="Annual Home Insurance ($)"
            type="number"
            value={homeInsuranceAnnual}
            onChange={(e) =>
              setHomeInsuranceAnnual(e.target.value === '' ? '' : Number(e.target.value))
            }
            fullWidth
            variant="outlined"
            inputProps={{ min: 0 }}
            InputProps={{ startAdornment: <InputAdornment position="start">$</InputAdornment> }}
          />
          <TextField
            label="Other Monthly Debts ($)"
            type="number"
            value={otherMonthlyDebts}
            onChange={(e) =>
              setOtherMonthlyDebts(e.target.value === '' ? '' : Number(e.target.value))
            }
            fullWidth
            variant="outlined"
            inputProps={{ min: 0 }}
            InputProps={{ startAdornment: <InputAdornment position="start">$</InputAdornment> }}
          />

          {/* Debt-to-Income Ratio */}
          <Box sx={{ gridColumn: { xs: 'span 1', md: 'span 2' }, mt: 2 }}>
            <Typography gutterBottom>Max Debt-to-Income Ratio (%)</Typography>
            <Slider
              value={typeof maxDebtToIncomeRatio === 'number' ? maxDebtToIncomeRatio : 0}
              onChange={(_, newValue) => setMaxDebtToIncomeRatio(newValue as number)}
              aria-labelledby="input-slider"
              valueLabelDisplay="auto"
              step={1}
              marks
              min={10}
              max={50}
              sx={{ width: '95%', margin: '0 auto' }}
            />
            <TextField
              value={maxDebtToIncomeRatio}
              onChange={(e) => setMaxDebtToIncomeRatio(Number(e.target.value))}
              type="number"
              inputProps={{
                step: 1,
                min: 10,
                max: 50,
                'aria-labelledby': 'input-slider',
              }}
              sx={{ width: '100px', ml: 'auto' }}
              InputProps={{ endAdornment: <InputAdornment position="end">%</InputAdornment> }}
            />
          </Box>
        </Box>
        <Button
          variant="contained"
          color="primary"
          onClick={calculateAffordability}
          fullWidth
          size="large"
        >
          Calculate Affordability
        </Button>
        {error && (
          <Alert severity="error" sx={{ mt: 2, borderRadius: 2 }}>
            {error}
          </Alert>
        )}
      </Paper>

      {affordableHomePrice > 0 && (
        <Paper elevation={3} sx={{ p: 4 }}>
          <Typography variant="h5" gutterBottom sx={{ mb: 2 }}>
            Affordability Summary
          </Typography>
          <Box sx={{ mb: 3 }}>
            <Typography variant="h6" color="primary">
              Estimated Affordable Home Price: ${affordableHomePrice.toFixed(2)}
            </Typography>
            <Typography variant="body1" sx={{ mt: 1 }}>
              Estimated Monthly Payment (PITI + PMI): ${estimatedMonthlyPayment.toFixed(2)}
            </Typography>
            <Typography variant="body2" sx={{ mt: 2 }}>
              *This calculation is an estimate based on your inputs and a common debt-to-income
              ratio approach. Actual affordability may vary based on lender criteria, credit score,
              and other factors.
            </Typography>
          </Box>
        </Paper>
      )}
    </Container>
  );
};

export default HomeAffordability;
