import { useQuery } from "@tanstack/react-query";
import { Freight } from "@edr/types";
import useAuth from "@/hooks/useAuth";
import { useBookingWindowSocket } from "@/features/bookingWindows/useBookingWindowSocket";
import { api } from "@/services/api";
import { isBookingLive } from "@/pages/bookings/BookingDetailPage/utils";
import { ACTIVE_STATUSES } from "./constants";

export function useMyPortalData(selectedProfileId?: string) {
  const { user, customer, company } = useAuth();

  // Live booking-window pushes: a phase transition on any lane invalidates the
  // windows queries below the moment it happens (poll below is only a fallback).
  useBookingWindowSocket(Boolean(user));

  const invoicesQuery = useQuery(api.invoices.listMy.queryOptions());
  const myInvoices = invoicesQuery.data ?? [];

  const companyProfiles = company?.company?.companyProfiles ?? [];

  const bookingsQuery = useQuery(
    api.bookings.list.queryOptions({
      input: {
        sortBy: "createdAt",
        sortOrder: "DESC",
        companyProfileId: selectedProfileId,
      },
      // The home tiles read each booking's status directly, but staff/system
      // transitions (operations accepting an order, batch selection, clearance
      // review) never push here. Poll while any booking is still live so those
      // changes surface — e.g. an accepted order leaving "Operation request
      // under review" — and stop once everything has settled.
      refetchInterval: (query) => {
        const items =
          (query.state.data as { items?: Freight.IBooking[] } | undefined)
            ?.items ?? [];
        return items.some((b) => isBookingLive(b.status)) ? 30_000 : false;
      },
    }),
  );

  const dashboardQuery = useQuery(
    api.companies.getDashboard.queryOptions({ input: selectedProfileId }),
  );

  // Upcoming/open booking windows on the customer's active-contract lanes.
  // Refetched every minute so "Open now" flips without a manual reload.
  const bookingWindowsQuery = useQuery(
    api.bookings.getMyBookingWindows.queryOptions({
      refetchInterval: 60_000,
    }),
  );
  const bookingWindows = bookingWindowsQuery.data ?? [];

  const contractsQuery = useQuery(
    api.contracts.list.queryOptions({
      input: {
        page: 1,
        pageSize: 50,
        sortBy: "createdAt",
        sortOrder: "DESC",
      },
    }),
  );

  const allContracts = contractsQuery.data?.items ?? [];
  const recentContracts = allContracts.slice(0, 5);

  const ACTIVE_CONTRACT_STATUSES = [
    "CONTRACT_ACTIVE",
    "FULLY_EXECUTED",
    "ACTIVE_SHIPMENT_IN_PROGRESS",
  ];
  const activeContractsCount = allContracts.filter((c) =>
    ACTIVE_CONTRACT_STATUSES.includes(c.status),
  ).length;

  const allBookings = bookingsQuery.data?.items ?? [];
  const activeBookings = allBookings.filter((b) =>
    ACTIVE_STATUSES.includes(b.status),
  );

  const weekAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
  const newActiveThisWeek = activeBookings.filter(
    (b) => new Date(b.createdAt).getTime() >= weekAgo,
  ).length;

  const outstandingInvoices = myInvoices.filter(
    (inv) =>
      inv.status === Freight.InvoiceStatus.Pending ||
      inv.status === Freight.InvoiceStatus.Overdue,
  );

  const totalOutstanding = outstandingInvoices.reduce(
    (sum, inv) => sum + Number(inv.totalAmount),
    0,
  );

  const displayName = user?.name?.en ?? user?.username ?? user?.email ?? "—";
  const companyName = (customer as any)?.companyName ?? displayName;

  const hour = new Date().getHours();
  const greeting =
    hour < 12
      ? "Good morning,"
      : hour < 18
        ? "Good afternoon,"
        : "Good evening,";

  const recentInvoices = myInvoices.slice(0, 3);

  const dashboard = dashboardQuery.data;
  const volumePoints = dashboard?.freightVolume.monthly ?? [];
  const maxVolume = Math.max(1, ...volumePoints.map((p) => p.tonnes));

  return {
    user,
    customer,
    companyProfiles,
    bookingsQuery,
    dashboardQuery,
    contractsQuery,
    invoicesQuery,
    bookingWindowsQuery,
    bookingWindows,
    allContracts,
    recentContracts,
    activeContractsCount,
    allBookings,
    activeBookings,
    newActiveThisWeek,
    outstandingInvoices,
    totalOutstanding,
    companyName,
    greeting,
    recentInvoices,
    dashboard,
    volumePoints,
    maxVolume,
    myInvoices,
  };
}
