"use client";

import { useMemo, useState } from "react";
import { useAuth } from "@/app/components/providers/auth-provider";
import type {
  OwnerDashboardParams,
  OwnerDashboardPeriod,
} from "@/lib/api/owner-dashboard";
import type { BestSellingProductsReportParams } from "@/lib/api/reports-best-selling-products";
import { getErrorMessage } from "@/lib/api/types";
import {
  formatOwnerDateRange,
  getDateRangeForPeriod,
  mapOwnerDashboardToViewModel,
  toOwnerDateParam,
} from "@/lib/dashboard/owner-dashboard";
import type { TopProduct } from "@/lib/dashboard/mock-data";
import {
  formatTodayDate,
  getGreeting,
  periodLabels,
} from "@/lib/dashboard/mock-data";
import { useBranches } from "@/lib/query/hooks/branches";
import { useOwnerDashboard } from "@/lib/query/hooks/owner-dashboard";
import { useBestSellingProductsReport } from "@/lib/query/hooks/reports-best-selling-products";
import {
  OwnerDateRangePicker,
  type OwnerDateRange,
} from "../owner/owner-date-range-picker";
import { FormSearchSelect } from "../ui/form-search-select";
import { MaterialIcon } from "../icons/nav-icons";
import { OwnerCategoryDonut } from "../owner/owner-category-donut";
import { StatCard, StatCardSkeleton, STAT_CARD_COUNT } from "./stat-card";
import { TopProducts } from "./top-products";
import { motion } from "motion/react";

const periods: OwnerDashboardPeriod[] = ["today", "week", "month"];
const ALL_BRANCHES_VALUE = "all";
const ALL_BRANCHES_LABEL = "Semua Cabang";
const TOP_PRODUCTS_LIMIT = 5;
const EMPTY_TOP_PRODUCTS: TopProduct[] = [];
const EMPTY_OWNER_VIEW = mapOwnerDashboardToViewModel({
  filters: {
    branchId: null,
    branchName: "Semua Cabang",
    period: "today",
    dateFrom: "",
    dateTo: "",
    comparisonLabel: "vs kemarin",
  },
  kpis: {
    totalSales: { value: 0, changePercent: null },
    orderCount: { value: 0, changePercent: null },
    avgTransaction: { value: 0, changePercent: null },
    activeTables: {
      active: 0,
      total: 0,
      label: "0 / 0",
      changePercent: null,
    },
  },
  topCategoriesByAmount: [],
  topCategoriesByQty: [],
});

function readStoredBranchId() {
  if (typeof window === "undefined") {
    return ALL_BRANCHES_VALUE;
  }

  return sessionStorage.getItem("selected_branch_id") ?? ALL_BRANCHES_VALUE;
}

function resolveBranchId(
  selectedBranchId: string,
  branchIds: Set<string>,
): string {
  if (selectedBranchId === ALL_BRANCHES_VALUE) {
    return ALL_BRANCHES_VALUE;
  }

  if (branchIds.size === 0 || branchIds.has(selectedBranchId)) {
    return selectedBranchId;
  }

  return ALL_BRANCHES_VALUE;
}

export function DashboardView() {
  const { user, roleLabel } = useAuth();
  const [selectedBranchId, setSelectedBranchId] = useState(readStoredBranchId);
  const [period, setPeriod] = useState<OwnerDashboardPeriod | null>("today");
  const [customDateRange, setCustomDateRange] = useState<OwnerDateRange>(() =>
    getDateRangeForPeriod("today"),
  );
  const [autoOpenCustomPicker, setAutoOpenCustomPicker] = useState(false);

  const displayName = user?.fullName || roleLabel;
  const isCustomPeriod = period === null;

  const branchesQuery = useBranches();
  const branches = branchesQuery.data ?? [];
  const branchIds = new Set(branches.map((branch) => String(branch.id)));
  const effectiveBranchId = resolveBranchId(selectedBranchId, branchIds);

  const branchOptions = [
    { value: ALL_BRANCHES_VALUE, label: ALL_BRANCHES_LABEL },
    ...branches.map((branch) => ({
      value: String(branch.id),
      label: branch.name,
    })),
  ];

  const parsedBranchId =
    effectiveBranchId !== ALL_BRANCHES_VALUE
      ? Number(effectiveBranchId)
      : undefined;

  const canFetchOwnerDashboard =
    effectiveBranchId === ALL_BRANCHES_VALUE ||
    (branchesQuery.isSuccess && branchIds.has(effectiveBranchId));

  const customDateFrom = toOwnerDateParam(customDateRange.start);
  const customDateTo = toOwnerDateParam(customDateRange.end);
  const customDateLabel = formatOwnerDateRange(
    customDateRange.start,
    customDateRange.end,
  );
  const filterKey = isCustomPeriod
    ? `custom-${customDateFrom}-${customDateTo}-${effectiveBranchId}`
    : `${period}-${effectiveBranchId}`;

  const ownerParams = useMemo<OwnerDashboardParams>(() => {
    const branchId = Number.isFinite(parsedBranchId)
      ? parsedBranchId
      : undefined;

    if (period != null) {
      return {
        period,
        ...(branchId != null ? { branchId } : {}),
      };
    }

    return {
      dateFrom: customDateFrom,
      dateTo: customDateTo,
      ...(branchId != null ? { branchId } : {}),
    };
  }, [period, customDateFrom, customDateTo, parsedBranchId]);

  const topProductsParams = useMemo<BestSellingProductsReportParams>(() => {
    const branchId = Number.isFinite(parsedBranchId)
      ? parsedBranchId
      : undefined;

    if (period != null) {
      return {
        period,
        limit: TOP_PRODUCTS_LIMIT,
        ...(branchId != null ? { branchId } : {}),
      };
    }

    return {
      dateFrom: customDateFrom,
      dateTo: customDateTo,
      limit: TOP_PRODUCTS_LIMIT,
      ...(branchId != null ? { branchId } : {}),
    };
  }, [period, customDateFrom, customDateTo, parsedBranchId]);

  const ownerDashboardQuery = useOwnerDashboard(ownerParams, {
    enabled: canFetchOwnerDashboard,
  });

  const topProductsQuery = useBestSellingProductsReport(topProductsParams, {
    enabled: canFetchOwnerDashboard,
  });

  const ownerData = ownerDashboardQuery.data
    ? mapOwnerDashboardToViewModel(ownerDashboardQuery.data)
    : EMPTY_OWNER_VIEW;

  const topProducts = useMemo<TopProduct[]>(() => {
    const report = topProductsQuery.data;

    if (!report || report.rows.length === 0) {
      return EMPTY_TOP_PRODUCTS;
    }

    const totalAmount = report.totals.amount || 0;

    return report.rows.map((row) => ({
      name: row.menuName,
      category: row.standName,
      sold: row.qty,
      revenue: row.amount,
      share:
        totalAmount > 0
          ? Math.round((row.amount / totalAmount) * 1000) / 10
          : 0,
    }));
  }, [topProductsQuery.data]);

  function handleBranchChange(branchId: string) {
    setSelectedBranchId(branchId);

    if (branchId === ALL_BRANCHES_VALUE) {
      sessionStorage.removeItem("selected_branch_id");
      return;
    }

    sessionStorage.setItem("selected_branch_id", branchId);
  }

  function handlePeriodChange(nextPeriod: OwnerDashboardPeriod) {
    setPeriod(nextPeriod);
    setAutoOpenCustomPicker(false);
  }

  function handleCustomPeriodClick() {
    setPeriod(null);
    setCustomDateRange((current) => current ?? getDateRangeForPeriod("today"));
    setAutoOpenCustomPicker(true);
  }

  function handleDateRangeChange(range: OwnerDateRange) {
    setPeriod(null);
    setCustomDateRange(range);
    setAutoOpenCustomPicker(false);
  }

  const ownerError =
    (branchesQuery.error
      ? getErrorMessage(branchesQuery.error, "Gagal memuat data cabang.")
      : null) ??
    (ownerDashboardQuery.error
      ? getErrorMessage(
          ownerDashboardQuery.error,
          "Gagal memuat data dashboard.",
        )
      : null) ??
    (topProductsQuery.error
      ? getErrorMessage(topProductsQuery.error, "Gagal memuat produk terlaris.")
      : null);

  const showOwnerLoading =
    ownerDashboardQuery.isPending && !ownerDashboardQuery.data;
  const showTopProductsLoading =
    topProductsQuery.isPending && !topProductsQuery.data;

  return (
    <div className="flex w-full min-w-0 flex-col gap-5">
      <motion.section
        initial={{ opacity: 0, y: 12 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ duration: 0.45, ease: [0.16, 1, 0.3, 1] }}
        className="relative rounded-lg border border-neutral-40 bg-neutral-10"
      >
        <div
          className="pointer-events-none absolute inset-0 overflow-hidden rounded-lg"
          aria-hidden
        >
          <div className="absolute -top-10 -right-10 size-40 rounded-full bg-secondary-100/60 blur-2xl" />
          <div className="absolute -bottom-12 -left-8 size-36 rounded-full bg-primary-100/50 blur-2xl" />
        </div>

        <div className="relative z-10 flex flex-col gap-5 p-5 sm:gap-6 sm:p-6">
          <div className="flex min-w-0 flex-col gap-2">
            <motion.p
              initial={{ opacity: 0, y: 8 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{
                duration: 0.4,
                delay: 0.05,
                ease: [0.16, 1, 0.3, 1],
              }}
              className="text-s-regular text-neutral-70"
            >
              {formatTodayDate()}
            </motion.p>
            <motion.h1
              initial={{ opacity: 0, y: 12 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{
                duration: 0.5,
                delay: 0.12,
                ease: [0.16, 1, 0.3, 1],
              }}
              className="heading-m text-neutral-100"
            >
              {getGreeting()}, {displayName}
            </motion.h1>
            <motion.p
              initial={{ opacity: 0, y: 10 }}
              animate={{ opacity: 1, y: 0 }}
              transition={{
                duration: 0.5,
                delay: 0.22,
                ease: [0.16, 1, 0.3, 1],
              }}
              className="text-m-regular max-w-xl text-neutral-80"
            >
              Pantau performa penjualan, pesanan aktif, dan menu terlaris INDUK
              KUPIE ACEH dalam satu tampilan.
            </motion.p>
          </div>

          <div className="flex flex-col gap-3 border-t border-neutral-40/80 pt-4">
            <div className="flex flex-col gap-3 lg:flex-row lg:items-end lg:gap-4">
              <div className="flex min-w-0 flex-1 flex-col gap-2">
                <p className="text-s-medium text-neutral-80">Periode cepat</p>
                <div
                  role="tablist"
                  aria-label="Periode cepat"
                  className="flex h-10 w-full min-w-0 items-stretch gap-1 rounded-lg border border-neutral-40 bg-neutral-20 p-1"
                >
                  {periods.map((item) => {
                    const isActive = period === item;

                    return (
                      <button
                        key={item}
                        type="button"
                        role="tab"
                        aria-selected={isActive}
                        onClick={() => handlePeriodChange(item)}
                        className={`text-s-medium sm:text-m-medium flex min-w-0 flex-1 items-center justify-center rounded-md px-1.5 whitespace-nowrap transition-colors sm:px-2 ${
                          isActive
                            ? "bg-neutral-10 text-primary-600 shadow-sm"
                            : "text-neutral-80 hover:bg-neutral-10/70 hover:text-neutral-100"
                        }`}
                      >
                        {periodLabels[item]}
                      </button>
                    );
                  })}

                  <button
                    type="button"
                    role="tab"
                    aria-selected={isCustomPeriod}
                    onClick={handleCustomPeriodClick}
                    className={`text-s-medium sm:text-m-medium flex min-w-0 flex-1 items-center justify-center rounded-md px-1.5 whitespace-nowrap transition-colors sm:px-2 ${
                      isCustomPeriod
                        ? "bg-neutral-10 text-primary-600 shadow-sm"
                        : "text-neutral-80 hover:bg-neutral-10/70 hover:text-neutral-100"
                    }`}
                  >
                    Custom
                  </button>
                </div>
              </div>

              {isCustomPeriod ? (
                <div className="relative z-30 w-full min-w-0 lg:w-[260px] lg:shrink-0">
                  <p className="text-s-medium mb-2 text-neutral-80">
                    Rentang tanggal
                  </p>
                  <OwnerDateRangePicker
                    value={customDateRange}
                    label={customDateLabel}
                    onChange={handleDateRangeChange}
                    variant="field"
                    active
                    autoOpen={autoOpenCustomPicker}
                    className="w-full"
                  />
                </div>
              ) : null}

              <div className="relative z-20 w-full min-w-0 lg:w-[240px] lg:shrink-0">
                {isCustomPeriod ? (
                  <p className="text-s-medium mb-2 text-neutral-80">Cabang</p>
                ) : null}
                <FormSearchSelect
                  id="dashboard-branch"
                  value={effectiveBranchId}
                  placeholder={
                    branchesQuery.isPending
                      ? "Memuat cabang..."
                      : ALL_BRANCHES_LABEL
                  }
                  searchPlaceholder="Cari cabang..."
                  disabled={branchesQuery.isPending}
                  options={branchOptions}
                  onChange={handleBranchChange}
                  className="w-full"
                />
              </div>
            </div>
          </div>
        </div>
      </motion.section>

      {ownerError && (
        <motion.p
          initial={{ opacity: 0, y: 8 }}
          animate={{ opacity: 1, y: 0 }}
          className="text-m-regular rounded-lg border border-danger-200 bg-danger-50 px-4 py-3 text-danger-700"
        >
          {ownerError}
        </motion.p>
      )}

      {showOwnerLoading ? (
        <div className="grid w-full min-w-0 gap-5 sm:grid-cols-2 xl:grid-cols-4">
          {Array.from({ length: STAT_CARD_COUNT }, (_, index) => (
            <StatCardSkeleton key={index} index={index} />
          ))}
        </div>
      ) : (
        <div
          key={filterKey}
          className="grid w-full min-w-0 gap-5 sm:grid-cols-2 xl:grid-cols-4"
        >
          {ownerData.stats.map((metric, index) => (
            <StatCard key={metric.label} metric={metric} index={index} />
          ))}
        </div>
      )}

      {showTopProductsLoading ? (
        <section className="rounded-lg border border-neutral-40 bg-neutral-10 p-5">
          <div className="mb-5">
            <h2 className="heading-s text-neutral-100">Produk Terlaris</h2>
            <p className="text-m-regular text-neutral-80">
              Menu dengan kontribusi penjualan tertinggi
            </p>
          </div>
          <div className="flex min-h-48 flex-col items-center justify-center gap-3 rounded-lg border border-dashed border-neutral-40 bg-neutral-20/50 px-6 py-10 text-center">
            <div className="flex size-14 items-center justify-center rounded-full bg-neutral-10 text-neutral-70 shadow-sm">
              <MaterialIcon name="progress_activity" size={28} />
            </div>
            <p className="text-m-regular text-neutral-80">
              Memuat produk terlaris...
            </p>
          </div>
        </section>
      ) : (
        <TopProducts key={`top-${filterKey}`} products={topProducts} />
      )}

      {showOwnerLoading ? (
        <p className="text-m-regular text-neutral-80">
          Memuat ringkasan kategori...
        </p>
      ) : (
        <div
          key={`categories-${filterKey}`}
          className="grid w-full min-w-0 gap-5 xl:grid-cols-2"
        >
          <OwnerCategoryDonut
            title="Top 4 Kategori Menu (Jumlah)"
            segments={ownerData.categoriesByAmount}
            valueType="amount"
          />
          <OwnerCategoryDonut
            title="Top 4 Kategori Menu (Qty)"
            segments={ownerData.categoriesByQty}
            valueType="qty"
          />
        </div>
      )}
    </div>
  );
}
