import React, { useState, useEffect } from "react";
import { useStore } from "@nanostores/react";
import type { Transaction } from "../types";
// Import store atoms and actions
import {
  currentAccountId as currentAccountIdStore,
  transactionToEdit as transactionToEditStore,
  cancelEditingTransaction,
  transactionSaved,
} from "../stores/transactionStore";

// Remove props that now come from the store
interface AddTransactionFormProps {}

export default function AddTransactionForm({}: AddTransactionFormProps) {
  // --- Read state from store ---
  const currentAccountId = useStore(currentAccountIdStore);
  const transactionToEdit = useStore(transactionToEditStore);

  // --- State Variables ---
  const [date, setDate] = useState("");
  const [description, setDescription] = useState("");
  const [amount, setAmount] = useState("");
  const [editingId, setEditingId] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const isEditMode = !!editingId;

  // --- Effects ---
  // Effect to set default date on mount
  useEffect(() => {
    // Only set default date if not editing
    if (!transactionToEdit) {
      setDate(new Date().toISOString().split("T")[0]);
    }
  }, [transactionToEdit]); // Rerun if edit mode changes

  // Effect to populate form when editing
  useEffect(() => {
    if (transactionToEdit) {
      setEditingId(transactionToEdit.id);
      // Format date correctly for input type="date"
      try {
        const dateObj = new Date(transactionToEdit.date);
        // Check if date is valid before formatting
        if (!isNaN(dateObj.getTime())) {
          // Adjust for timezone offset to prevent date shifting
          const timezoneOffset = dateObj.getTimezoneOffset() * 60000; //offset in milliseconds
          const adjustedDate = new Date(dateObj.getTime() - timezoneOffset);
          setDate(adjustedDate.toISOString().split("T")[0]);
        } else {
          console.warn(
            "Invalid date received for editing:",
            transactionToEdit.date
          );
          setDate(""); // Set to empty if invalid
        }
      } catch (e) {
        console.error("Error parsing date for editing:", e);
        setDate(""); // Set to empty on error
      }
      setDescription(transactionToEdit.description);
      setAmount(transactionToEdit.amount.toString());
      setError(null); // Clear errors when starting edit
    } else {
      // Reset form if transactionToEdit becomes null (e.g., after saving or cancelling)
      // but only if not already resetting via handleCancel or handleSubmit
      if (!isLoading) {
        resetForm();
      }
    }
  }, [transactionToEdit, isLoading]); // Add isLoading dependency

  // --- Helper Functions ---
  const resetForm = () => {
    setEditingId(null);
    setDate(new Date().toISOString().split("T")[0]);
    setDescription("");
    setAmount("");
    setError(null);
    // Don't reset isLoading here, it's handled in submit/cancel
  };

  const validateForm = (): string[] => {
    const errors: string[] = [];
    if (!description || description.trim().length < 2) {
      errors.push("Description must be at least 2 characters long");
    }
    if (!amount) {
      errors.push("Amount is required");
    } else {
      const amountNum = parseFloat(amount);
      if (isNaN(amountNum)) {
        errors.push("Amount must be a valid number");
      } else if (amountNum === 0) {
        errors.push("Amount cannot be zero");
      }
    }
    if (!date) {
      errors.push("Date is required");
    } else {
      try {
        const dateObj = new Date(date + "T00:00:00"); // Treat input as local date
        if (isNaN(dateObj.getTime())) {
          errors.push("Invalid date format");
        }
      } catch (e) {
        errors.push("Invalid date format");
      }
    }
    return errors;
  };

  // --- Event Handlers ---
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError(null);

    if (isLoading || !currentAccountId) {
      if (!currentAccountId) setError("No account selected.");
      return;
    }

    const validationErrors = validateForm();
    if (validationErrors.length > 0) {
      setError(validationErrors.join(". "));
      return;
    }

    setIsLoading(true);

    try {
      // Ensure date is sent in a consistent format (e.g., YYYY-MM-DD)
      // The API should handle parsing this.
      const transactionData = {
        accountId: currentAccountId,
        date: date, // Send as YYYY-MM-DD string
        description: description.trim(),
        amount: parseFloat(amount),
      };

      const method = editingId ? "PUT" : "POST";
      const url = editingId
        ? `/api/transactions/${editingId}`
        : "/api/transactions";

      const response = await fetch(url, {
        method,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(transactionData),
      });

      if (!response.ok) {
        let errorMsg = `Failed to ${
          isEditMode ? "update" : "create"
        } transaction`;
        try {
          const errorData = await response.json();
          errorMsg = errorData.error || errorMsg;
        } catch (jsonError) {
          // Ignore if response is not JSON
          errorMsg = `${response.status}: ${response.statusText}`;
        }
        throw new Error(errorMsg);
      }

      const savedTransaction: Transaction = await response.json();
      transactionSaved(savedTransaction); // Call store action instead of prop callback
      resetForm(); // Reset form on success
    } catch (err) {
      setError(
        err instanceof Error ? err.message : "An unexpected error occurred"
      );
    } finally {
      setIsLoading(false);
    }
  };

  const handleCancel = () => {
    resetForm();
    cancelEditingTransaction(); // Call store action instead of prop callback
  };

  // --- JSX ---
  return (
    <form id="add-transaction-form-react" onSubmit={handleSubmit} noValidate>
      <h4>{isEditMode ? "Edit Transaction" : "New Transaction"}</h4>
      {error && <div className="error-message">{error}</div>}

      <div className="form-group">
        <label htmlFor="txn-date-react">Date</label>
        <input
          type="date"
          id="txn-date-react"
          name="date"
          value={date}
          onChange={(e) => setDate(e.target.value)}
          required
          disabled={isLoading}
        />
      </div>
      <div className="form-group">
        <label htmlFor="txn-description-react">Description</label>
        <input
          type="text"
          id="txn-description-react"
          name="description"
          value={description}
          onChange={(e) => setDescription(e.target.value)}
          required
          minLength={2}
          maxLength={100}
          placeholder="e.g. Groceries"
          disabled={isLoading}
        />
      </div>
      <div className="form-group">
        <label htmlFor="txn-amount-react">Amount</label>
        <input
          type="number"
          id="txn-amount-react"
          name="amount"
          value={amount}
          onChange={(e) => setAmount(e.target.value)}
          step="0.01"
          required
          placeholder="e.g. -25.50 or 1200.00"
          disabled={isLoading}
        />
        <small className="help-text">
          Use negative numbers for expenses (e.g., -50.00)
        </small>
      </div>
      <div className="button-group">
        <button
          type="submit"
          className={`form-submit-btn ${isLoading ? "loading" : ""}`}
          disabled={isLoading}
        >
          {isLoading
            ? "Saving..."
            : isEditMode
            ? "Update Transaction"
            : "Save Transaction"}
        </button>
        {isEditMode && (
          <button
            type="button"
            className="cancel-btn"
            onClick={handleCancel}
            disabled={isLoading}
          >
            Cancel
          </button>
        )}
      </div>
    </form>
  );
}
