"use client";

import { isApiSuccess } from "@/lib/api-messages";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { LineChart } from "lucide-react";
import { toast } from "sonner";

import { ListPageCard } from "@/app/dashboard/_components";
import { useClearFiltersRefresh } from "@/app/dashboard/_components/data-table";
import { FormSaveBar } from "@/app/dashboard/_components/form";
import { ErrorBanner } from "@/components/shared/error-banner";
import { requestDashboardApi } from "@/lib/dashboard-api-client";

import {
  buildIsinMarketPriceHref,
  DEFAULT_PAGE_SIZE,
} from "./constants";
import { IsinMarketPriceHeaderActions } from "./list-header-actions";
import { IsinMarketPriceTable } from "./isin-market-price-table";
import { MarketPriceTabs } from "./market-price-tabs";
import type {
  IsinMarketPriceRow,
  MarketPriceTab,
  MarketPriceTableModel,
} from "./schema";

const UPDATE_HREF = "/dashboard/master-table/isin-assets-market-price/update";

type Props = {
  activeModel: MarketPriceTableModel;
  data: IsinMarketPriceRow[];
  tabs: MarketPriceTab[];
  totalCount: number;
  page: number;
  pageSize: number;
  pageCount: number;
  filters: {
    isin: string;
    industry: string;
    sector: string;
  };
  errorMessage?: string | null;
};

function buildPriceMap(rows: IsinMarketPriceRow[]): Record<string, string> {
  return Object.fromEntries(rows.map((row) => [row.isin, row.marketPrice]));
}

export function IsinMarketPricePageClient({
  activeModel,
  data,
  tabs,
  totalCount,
  page,
  pageSize,
  pageCount,
  filters,
  errorMessage = null,
}: Props) {
  const router = useRouter();
  const { isRefreshing, onRefresh } = useClearFiltersRefresh({
    clearToHref: buildIsinMarketPriceHref({ model: activeModel, page: 1 }),
  });
  const [isSaving, setIsSaving] = useState(false);
  const [prices, setPrices] = useState<Record<string, string>>(() =>
    buildPriceMap(data),
  );

  useEffect(() => {
    setPrices(buildPriceMap(data));
  }, [data]);

  const navigate = useCallback(
    (next: {
      model?: MarketPriceTableModel;
      isin?: string;
      industry?: string;
      sector?: string;
      page?: number;
      pageSize?: number;
    }) => {
      router.push(
        buildIsinMarketPriceHref({
          model: next.model ?? activeModel,
          isin: next.isin ?? filters.isin,
          industry: next.industry ?? filters.industry,
          sector: next.sector ?? filters.sector,
          page: next.page ?? page,
          pageSize: next.pageSize ?? pageSize,
        }),
        { scroll: false },
      );
    },
    [activeModel, filters.industry, filters.isin, filters.sector, page, pageSize, router],
  );

  const onPriceChange = useCallback((isin: string, value: string) => {
    setPrices((prev) => ({ ...prev, [isin]: value }));
  }, []);

  const onSubmit = async (event: React.FormEvent) => {
    event.preventDefault();

    const changedPrices: Record<string, string> = {};
    for (const row of data) {
      const next = (prices[row.isin] ?? "").trim();
      const prev = (row.marketPrice ?? "").trim();
      if (next !== prev) {
        changedPrices[row.isin] = next;
      }
    }

    if (!Object.keys(changedPrices).length) {
      toast.message("No market price changes to save.");
      return;
    }

    setIsSaving(true);
    try {
      const response = await requestDashboardApi<{
        status?: string;
        message?: string;
      }>({
        url: UPDATE_HREF,
        method: "POST",
        body: {
          model: activeModel,
          prices: changedPrices,
        },
        fallbackError: "Market prices could not be updated.",
        validate: (payload) => isApiSuccess(payload),
      });

      toast.success(response.message ?? "Market prices updated.");
      router.refresh();
    } catch (error) {
      toast.error(
        error instanceof Error
          ? error.message
          : "Market prices could not be updated.",
      );
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <form onSubmit={(event) => void onSubmit(event)} className="pb-4">
      <ListPageCard
        icon={LineChart}
        title="ISIN Assets Market Price"
        description="Update market prices by asset table."
        breadcrumb={[
          { label: "Master Table" },
          { label: "ISIN Assets Market Price" },
        ]}
        actions={
          <IsinMarketPriceHeaderActions
            isRefreshing={isRefreshing}
            onRefresh={onRefresh}
          />
        }
      >
        <ErrorBanner message={errorMessage} className="mb-4" />
        <div className="space-y-4">
          <MarketPriceTabs
            activeModel={activeModel}
            tabs={tabs}
            pageSize={pageSize === DEFAULT_PAGE_SIZE ? undefined : pageSize}
          />
          <IsinMarketPriceTable
            data={data}
            totalCount={totalCount}
            page={page}
            pageSize={pageSize}
            pageCount={pageCount}
            filters={filters}
            prices={prices}
            onPriceChange={onPriceChange}
            onNavigate={navigate}
          />
        </div>
      </ListPageCard>

      <FormSaveBar isSaving={isSaving} saveLabel="Update market price" />
    </form>
  );
}
