import React, { useState, useEffect } from "react";
import { Link } from "react-router";
import { rentalAPI, userAPI, stripeAPI } from "../services/api";
import { Rental, User } from "../types";
import StripeConnectOnboarding from "../components/StripeConnectOnboarding";
import EarningsStatus from "../components/EarningsStatus";

interface EarningsData {
  totalEarnings: number;
  pendingEarnings: number;
  completedEarnings: number;
  rentalsWithEarnings: Rental[];
}

interface AccountStatus {
  detailsSubmitted: boolean;
  payoutsEnabled: boolean;
}

const EarningsDashboard: React.FC = () => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [earningsData, setEarningsData] = useState<EarningsData | null>(null);
  const [userProfile, setUserProfile] = useState<User | null>(null);
  const [accountStatus, setAccountStatus] = useState<AccountStatus | null>(
    null
  );
  const [showOnboarding, setShowOnboarding] = useState(false);

  useEffect(() => {
    fetchUserProfile();
    fetchEarningsData();
  }, []);

  const fetchUserProfile = async () => {
    try {
      const response = await userAPI.getProfile();
      setUserProfile(response.data);

      // If user has a Stripe account, fetch account status
      if (response.data.stripeConnectedAccountId) {
        await fetchAccountStatus();
      }
    } catch (err) {
      console.error("Failed to fetch user profile:", err);
    }
  };

  const fetchAccountStatus = async () => {
    try {
      const response = await stripeAPI.getAccountStatus();
      setAccountStatus({
        detailsSubmitted: response.data.detailsSubmitted,
        payoutsEnabled: response.data.payoutsEnabled,
      });
    } catch (err) {
      console.error("Failed to fetch account status:", err);
    }
  };

  const fetchEarningsData = async () => {
    try {
      // Get completed rentals where user is the owner
      const response = await rentalAPI.getListings();
      const rentals = response.data || [];

      // Filter for completed rentals with earnings data
      const completedRentals = rentals.filter(
        (rental: Rental) => rental.status === "completed" && rental.payoutAmount
      );

      // Calculate earnings - convert string values to numbers
      const totalEarnings = completedRentals.reduce(
        (sum: number, rental: Rental) =>
          sum + parseFloat(rental.payoutAmount?.toString() || "0"),
        0
      );

      const pendingEarnings = completedRentals
        .filter((rental: Rental) => rental.bankDepositStatus !== "paid")
        .reduce(
          (sum: number, rental: Rental) =>
            sum + parseFloat(rental.payoutAmount?.toString() || "0"),
          0
        );

      const completedEarnings = completedRentals
        .filter((rental: Rental) => rental.bankDepositStatus === "paid")
        .reduce(
          (sum: number, rental: Rental) =>
            sum + parseFloat(rental.payoutAmount?.toString() || "0"),
          0
        );

      setEarningsData({
        totalEarnings,
        pendingEarnings,
        completedEarnings,
        rentalsWithEarnings: completedRentals,
      });
    } catch (err: any) {
      setError(err.response?.data?.message || "Failed to fetch earnings data");
    } finally {
      setLoading(false);
    }
  };

  const handleSetupComplete = () => {
    setShowOnboarding(false);
    fetchUserProfile(); // Refresh user profile after setup
    fetchEarningsData();
  };

  if (loading) {
    return (
      <div className="container mt-5">
        <div className="text-center">
          <div className="spinner-border" role="status">
            <span className="visually-hidden">Loading...</span>
          </div>
        </div>
      </div>
    );
  }

  const hasStripeAccount = !!userProfile?.stripeConnectedAccountId;
  const isOnboardingComplete = accountStatus?.detailsSubmitted ?? false;
  const payoutsEnabled = accountStatus?.payoutsEnabled ?? true;

  // Don't show setup card until we have account status (if user has a Stripe account)
  // This prevents the setup card from flashing briefly while fetching account status
  const accountStatusLoading = hasStripeAccount && accountStatus === null;

  // Show setup card if: no account, onboarding incomplete, or payouts disabled
  const showSetupCard =
    !accountStatusLoading &&
    (!hasStripeAccount || !isOnboardingComplete || !payoutsEnabled);

  return (
    <div className="container mt-4">
      <div className="row">
        <div className="col-12">
          <h1>Earnings</h1>
          <p className="text-muted">
            Manage your rental earnings and payment setup.{" "}
            <Link to="/faq" target="_blank">
              Calculate what you can earn here
            </Link>{" "}
            or <Link to="/faq#earnings">learn how payouts work</Link>.
          </p>
        </div>
      </div>

      {error && (
        <div className="alert alert-danger" role="alert">
          {error}
        </div>
      )}

      {/* Earnings Setup - show if not fully set up or payouts disabled */}
      {showSetupCard && (
        <div className="card mb-4">
          <div className="card-header">
            <h5 className="mb-0">Earnings Setup</h5>
          </div>
          <div className="card-body">
            <EarningsStatus
              hasStripeAccount={hasStripeAccount}
              isOnboardingComplete={isOnboardingComplete}
              payoutsEnabled={payoutsEnabled}
              onSetupClick={() => setShowOnboarding(true)}
            />
          </div>
        </div>
      )}

      <div className="row">
        <div className="col-12">
          {/* Earnings Overview */}
          <div className="card mb-4">
            <div className="card-header">
              <h5 className="mb-0">Earnings Overview</h5>
            </div>
            <div className="card-body">
              <div className="row text-center">
                <div className="col-md-4">
                  <h3 className="text-primary">
                    ${(earningsData?.totalEarnings || 0).toFixed(2)}
                  </h3>
                  <p className="text-muted">Total Earnings</p>
                </div>
                <div className="col-md-4">
                  <h3 className="text-warning">
                    ${(earningsData?.pendingEarnings || 0).toFixed(2)}
                  </h3>
                  <p className="text-muted">Pending Earnings</p>
                </div>
                <div className="col-md-4">
                  <h3 className="text-success">
                    ${(earningsData?.completedEarnings || 0).toFixed(2)}
                  </h3>
                  <p className="text-muted">Paid Out</p>
                </div>
              </div>
            </div>
          </div>

          {/* Earnings History */}
          <div className="card mb-4">
            <div className="card-header">
              <h5 className="mb-0">Earnings History</h5>
            </div>
            <div className="card-body">
              {earningsData?.rentalsWithEarnings.length === 0 ? (
                <p className="text-muted text-center">
                  No completed rentals yet
                </p>
              ) : (
                <div className="table-responsive">
                  <table className="table">
                    <thead>
                      <tr>
                        <th>Item</th>
                        <th>Rental Period</th>
                        <th>Total Amount</th>
                        <th>Your Earnings</th>
                        <th>Status</th>
                      </tr>
                    </thead>
                    <tbody>
                      {earningsData?.rentalsWithEarnings.map((rental) => (
                        <tr key={rental.id}>
                          <td>
                            <Link to={`/items/${rental.itemId}`}>
                              {rental.item?.name || "Item"}
                            </Link>
                          </td>
                          <td>
                            <small>
                              {new Date(rental.startDateTime).toLocaleString()}
                              <br />
                              to
                              <br />
                              {new Date(rental.endDateTime).toLocaleString()}
                            </small>
                          </td>
                          <td>
                            $
                            {parseFloat(
                              rental.totalAmount?.toString() || "0"
                            ).toFixed(2)}
                          </td>
                          <td className="text-success">
                            <strong>
                              $
                              {parseFloat(
                                rental.payoutAmount?.toString() || "0"
                              ).toFixed(2)}
                            </strong>
                          </td>
                          <td>
                            {(() => {
                              // Determine badge based on bank deposit and payout status
                              let badgeClass = "bg-secondary";
                              let badgeLabel = "Pending";
                              let badgeTooltip =
                                "Waiting for rental to complete or Stripe setup.";

                              if (rental.bankDepositStatus === "paid") {
                                badgeClass = "bg-success";
                                badgeLabel = "Deposited";
                                badgeTooltip = rental.bankDepositAt
                                  ? `Deposited to your bank on ${new Date(
                                      rental.bankDepositAt
                                    ).toLocaleDateString()}`
                                  : "Funds deposited to your bank account.";
                              } else if (
                                rental.bankDepositStatus === "failed"
                              ) {
                                badgeClass = "bg-danger";
                                badgeLabel = "Deposit Failed";
                                badgeTooltip =
                                  "Bank deposit failed. Please check your Stripe dashboard.";
                              } else if (
                                rental.bankDepositStatus === "in_transit"
                              ) {
                                badgeClass = "bg-info";
                                badgeLabel = "In Transit to Bank";
                                badgeTooltip =
                                  "Funds are on their way to your bank.";
                              } else if (rental.payoutStatus === "completed") {
                                badgeClass = "bg-info";
                                badgeLabel = "Transferred to Stripe";
                                badgeTooltip =
                                  "In your Stripe balance. Bank deposit in 2-7 business days.";
                              } else if (rental.payoutStatus === "failed") {
                                badgeClass = "bg-danger";
                                badgeLabel = "Transfer Failed";
                                badgeTooltip =
                                  "Transfer failed. We'll retry automatically.";
                              }

                              return (
                                <span
                                  className={`badge ${badgeClass}`}
                                  title={badgeTooltip}
                                  style={{ cursor: "help" }}
                                >
                                  {badgeLabel}
                                </span>
                              );
                            })()}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* Stripe Connect Onboarding Modal */}
      {showOnboarding && (
        <StripeConnectOnboarding
          onComplete={handleSetupComplete}
          onCancel={() => setShowOnboarding(false)}
          hasExistingAccount={hasStripeAccount}
        />
      )}
    </div>
  );
};

export default EarningsDashboard;
