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

export default function AddTransactionForm() {
  // --- 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 [successMessage, setSuccessMessage] = useState<string | null>(null);

  const isEditMode = !!editingId;

  // --- Effects ---
  // Effect to set default date on mount
  useEffect(() => {
    if (!transactionToEdit) {
      setDate(new Date().toISOString().split('T')[0]);
    }
  }, [transactionToEdit]);

  // Effect to populate form when editing
  useEffect(() => {
    if (transactionToEdit) {
      setEditingId(transactionToEdit.id);
      try {
        const dateObj = new Date(transactionToEdit.date);
        if (!Number.isNaN(dateObj.getTime())) {
          setDate(dateObj.toISOString().split('T')[0]);
        } else {
          console.warn('Invalid date received for editing:', transactionToEdit.date);
          setDate('');
        }
      } catch (e) {
        console.error('Error parsing date for editing:', e);
        setDate('');
      }
      setDescription(transactionToEdit.description);
      setAmount(transactionToEdit.amount.toString());
      setError(null);
      setSuccessMessage(null);
    } else if (!isLoading) {
      resetForm();
    }
  }, [transactionToEdit, isLoading]);

  // Clear success message after 5 seconds
  useEffect(() => {
    if (successMessage) {
      const timer = setTimeout(() => {
        setSuccessMessage(null);
      }, 5000);
      return () => clearTimeout(timer);
    }
  }, [successMessage]);

  // --- Helper Functions ---
  const resetForm = () => {
    setEditingId(null);
    setDate(new Date().toISOString().split('T')[0]);
    setDescription('');
    setAmount('');
    setError(null);
    setSuccessMessage(null);
  };

  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 = Number.parseFloat(amount);
      if (Number.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`);
        if (Number.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);
    setSuccessMessage(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 {
      const transactionData = {
        accountId: currentAccountId,
        date: date,
        description: description.trim(),
        amount: Number.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) {
          errorMsg = `${response.status}: ${response.statusText}`;
        }
        throw new Error(errorMsg);
      }

      const savedTransaction: Transaction = await response.json();

      // First notify about the saved transaction
      transactionSaved(savedTransaction);

      // Then explicitly trigger a refresh to ensure balance updates
      triggerRefresh();

      // Set success message before clearing form
      setSuccessMessage(
        isEditMode ? 'Transaction updated successfully' : 'Transaction created successfully',
      );

      // Only reset the form after the success message is shown
      setTimeout(() => {
        resetForm();
        // Optionally collapse the form after success
        const addTransactionSection = document.getElementById('add-transaction-section');
        const toggleAddTxnBtn = document.getElementById('toggle-add-txn-btn');
        if (addTransactionSection?.classList.contains('expanded')) {
          addTransactionSection.classList.replace('expanded', 'collapsed');
          toggleAddTxnBtn?.setAttribute('aria-expanded', 'false');
        }
      }, 2000);
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';
      setError(errorMessage);
      setSuccessMessage(null);
    } finally {
      setIsLoading(false);
    }
  };

  const handleCancel = () => {
    resetForm();
    cancelEditingTransaction();
  };

  // --- JSX ---
  return (
    <form id="add-transaction-form-react" role="form" onSubmit={handleSubmit} noValidate>
      <h4>{isEditMode ? 'Edit Transaction' : 'New Transaction'}</h4>
      {error && (
        <div className="error-message" data-testid="error-message">
          {error}
        </div>
      )}
      {successMessage && (
        <div className="success-message" data-testid="success-message">
          {successMessage}
        </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>
  );
}
