import { useCallback, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { ArrowLeft, Link2, RefreshCw } from 'lucide-react';
import { toast } from 'sonner';
import { api } from '@/api';
import { errMessage } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import BillModal from '@/components/BillModal';
import SubscriptionCatalogSection from '@/components/SubscriptionCatalogSection';
import type { Bill, Category } from '@/types';

export default function SubscriptionCatalogPage() {
  const [catalogKey, setCatalogKey] = useState(0);
  const [subscriptions, setSubscriptions] = useState<Bill[]>([]);
  const [categories, setCategories] = useState<Category[]>([]);
  const [modal, setModal] = useState<{ bill: Bill } | null>(null);

  const refreshSubscriptions = useCallback(async () => {
    try {
      const [subscriptionData, categoryData] = await Promise.all([
        api.subscriptions() as Promise<{ subscriptions?: Bill[] }>,
        api.categories(),
      ]);
      setSubscriptions(subscriptionData?.subscriptions || []);
      setCategories(Array.isArray(categoryData) ? categoryData : []);
    } catch (err) {
      toast.error(errMessage(err, 'Subscriptions could not be refreshed.'));
    }
  }, []);

  useEffect(() => {
    refreshSubscriptions();
  }, [refreshSubscriptions]);

  function openBillEditor(billId: number) {
    const bill = subscriptions.find(item => item.id === billId) || ({ id: billId } as Bill);
    setModal({ bill });
  }

  return (
    <div className="mx-auto w-full max-w-6xl space-y-6">
      <div className="flex flex-col gap-4 lg:flex-row lg:items-end lg:justify-between">
        <div className="min-w-0">
          <p className="mb-1 text-[11px] font-semibold uppercase tracking-[0.15em] text-muted-foreground">
            Matching Tools
          </p>
          <h1 className="text-3xl font-semibold tracking-tight">Service Catalog</h1>
          <p className="mt-1 max-w-2xl text-sm text-muted-foreground">
            Link tracked subscriptions to known services and tune bank descriptors so future recommendations are more accurate.
          </p>
        </div>
        <div className="grid grid-cols-2 gap-2 sm:flex sm:flex-wrap">
          <Button asChild type="button" variant="outline" className="gap-2">
            <Link to="/subscriptions">
              <ArrowLeft className="h-4 w-4" />
              Subscriptions
            </Link>
          </Button>
          <Button
            type="button"
            variant="outline"
            className="gap-2"
            onClick={() => setCatalogKey(key => key + 1)}
          >
            <RefreshCw className="h-4 w-4" />
            Refresh
          </Button>
        </div>
      </div>

      <div className="rounded-lg border border-border/70 bg-card/80 p-4">
        <div className="flex items-start gap-3">
          <span className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary">
            <Link2 className="h-4 w-4" />
          </span>
          <div className="min-w-0">
            <p className="text-sm font-semibold text-foreground">This page improves matching, not discovery.</p>
            <p className="mt-1 text-sm text-muted-foreground">
              Recommendations on the Subscriptions page come from bank transactions. Use this catalog when a service needs a better descriptor or an existing bill should be linked to a known service.
            </p>
          </div>
        </div>
      </div>

      <SubscriptionCatalogSection
        key={catalogKey}
        onEditBill={openBillEditor}
        onTrackComplete={async () => {
          await refreshSubscriptions();
          setCatalogKey(key => key + 1);
        }}
      />

      {modal && (
        <BillModal
          key={modal.bill?.id ? `catalog-edit-${modal.bill.id}` : 'catalog-edit'}
          bill={modal.bill}
          categories={categories}
          onClose={() => setModal(null)}
          onSave={async () => {
            setModal(null);
            await refreshSubscriptions();
            setCatalogKey(key => key + 1);
          }}
        />
      )}
    </div>
  );
}
