"use client";

import { useEffect, useRef, useState } from "react";
import { useSearchParams } from "next/navigation";
import { QueryTabs } from "@/components/shared/query-controls";
import {
  deleteParentRfid,
  deleteRfidCard,
  fetchParentRfid,
  fetchParentRfidPage,
  fetchRfidOptions,
  fetchRfidCard,
  fetchRfidPage,
  saveParentRfid,
  saveRfidCard,
} from "./client-api";
import { parseRfidListState } from "./query";
import { RFIDCardTab } from "./rfid-card-tab";
import { RFIDGroupTab } from "./rfid-group-tab";
import type {
  RfidCardFormValues,
  RfidCardRecord,
  RfidFormOptions,
  RfidGroupFormValues,
  RfidGroupRecord,
} from "./types";
import type { Pagination } from "@/lib/list-query";

const emptyPagination: Pagination = {
  page: 1,
  pages: 1,
  limit: 25,
  total: 0,
  start: 0,
  end: 0,
};

const emptyOptions: RfidFormOptions = {
  organizations: [],
  users: [],
  groups: [],
  defaultOrganizationCode: "",
};

type ActionToast = { kind: "success" | "error"; message: string };

function messageFrom(error: unknown, fallback: string) {
  return error instanceof Error && error.message.trim() ? error.message : fallback;
}

export function RFIDView() {
  const params = useSearchParams();
  const queryString = params.toString();
  const { tab } = parseRfidListState(new URLSearchParams(queryString));
  const [options, setOptions] = useState<RfidFormOptions>();
  const optionsRef = useRef<RfidFormOptions | undefined>(undefined);
  const [cards, setCards] = useState<RfidCardRecord[]>([]);
  const [groups, setGroups] = useState<RfidGroupRecord[]>([]);
  const [pagination, setPagination] = useState<Pagination>(emptyPagination);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState("");
  const [refreshVersion, setRefreshVersion] = useState(0);
  const [toast, setToast] = useState<ActionToast>();

  useEffect(() => {
    if (!toast) return;
    const timeout = setTimeout(() => setToast(undefined), 5000);
    return () => clearTimeout(timeout);
  }, [toast]);

  useEffect(() => {
    let cancelled = false;
    const query = new URLSearchParams(queryString);
    query.set("paginate_enabled", "true");
    query.set("paginate_limit", query.get("paginate_limit") || "25");
    query.set("paginate_page", query.get("paginate_page") || "1");

    async function load() {
      setLoading(true);
      setLoadError("");
      let currentOptions = optionsRef.current;
      let optionsError = "";
      const optionsPromise = currentOptions
        ? Promise.resolve(currentOptions)
        : fetchRfidOptions().then((value) => {
            currentOptions = value;
            optionsRef.current = value;
            setOptions(value);
            return value;
          }).catch((error: unknown) => {
            optionsError = messageFrom(error, "Unable to load RFID options.");
            return emptyOptions;
          });

      try {
        if (tab === "group") {
          const [page, resolvedOptions] = await Promise.all([
            fetchParentRfidPage(query),
            optionsPromise,
          ]);
          if (cancelled) return;
          if (!optionsRef.current && resolvedOptions !== emptyOptions) {
            optionsRef.current = resolvedOptions;
            setOptions(resolvedOptions);
          }
          setGroups(page.records);
          setCards([]);
          setPagination(page.pagination);
          setLoadError(optionsError);
        } else {
          const [page, resolvedOptions] = await Promise.all([
            fetchRfidPage(query),
            optionsPromise,
          ]);
          if (cancelled) return;
          if (!optionsRef.current && resolvedOptions !== emptyOptions) {
            optionsRef.current = resolvedOptions;
            setOptions(resolvedOptions);
          }
          setCards(page.records);
          setGroups(resolvedOptions.groups);
          setPagination(page.pagination);
          setLoadError(optionsError);
        }
      } catch (error) {
        if (cancelled) return;
        setLoadError(messageFrom(error, tab === "group" ? "Unable to load RFID groups." : "Unable to load RFID cards."));
        setPagination(emptyPagination);
        if (tab === "group") setGroups([]);
        else setCards([]);
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    void load();
    return () => {
      cancelled = true;
    };
  }, [queryString, refreshVersion, tab]);

  function refresh() {
    setRefreshVersion((version) => version + 1);
  }

  function notify(kind: ActionToast["kind"], message: string) {
    setToast({ kind, message });
  }

  async function createCard(values: RfidCardFormValues) {
    try {
      const result = await saveRfidCard(undefined, values);
      notify("success", result.message || "RFID card created successfully.");
      refresh();
      return true;
    } catch (error) {
      notify("error", messageFrom(error, "Unable to create the RFID card."));
      return false;
    }
  }

  async function updateCard(id: string, values: RfidCardFormValues) {
    try {
      const result = await saveRfidCard(id, values);
      notify("success", result.message || "RFID card updated successfully.");
      refresh();
      return true;
    } catch (error) {
      notify("error", messageFrom(error, "Unable to update the RFID card."));
      return false;
    }
  }

  async function removeCard(id: string) {
    try {
      const message = await deleteRfidCard(id);
      notify("success", message || "RFID card deleted successfully.");
      refresh();
      return true;
    } catch (error) {
      notify("error", messageFrom(error, "Unable to delete the RFID card."));
      return false;
    }
  }

  async function createGroup(values: RfidGroupFormValues) {
    try {
      const result = await saveParentRfid(undefined, values);
      notify("success", result.message || "RFID group created successfully.");
      refresh();
      return true;
    } catch (error) {
      notify("error", messageFrom(error, "Unable to create the RFID group."));
      return false;
    }
  }

  async function updateGroup(id: string, values: RfidGroupFormValues) {
    try {
      const result = await saveParentRfid(id, values);
      notify("success", result.message || "RFID group updated successfully.");
      refresh();
      return true;
    } catch (error) {
      notify("error", messageFrom(error, "Unable to update the RFID group."));
      return false;
    }
  }

  async function removeGroup(id: string) {
    try {
      const message = await deleteParentRfid(id);
      notify("success", message || "RFID group deleted successfully.");
      refresh();
      return true;
    } catch (error) {
      notify("error", messageFrom(error, "Unable to delete the RFID group."));
      return false;
    }
  }

  async function loadCard(id: string) {
    try {
      return await fetchRfidCard(id);
    } catch (error) {
      notify("error", messageFrom(error, "Unable to load RFID details."));
      return null;
    }
  }

  async function loadGroup(id: string) {
    try {
      return await fetchParentRfid(id);
    } catch (error) {
      notify("error", messageFrom(error, "Unable to load RFID group details."));
      return null;
    }
  }

  const currentOptions = options ?? emptyOptions;

  return (
    <>
      <QueryTabs
        active={tab}
        items={[
          { id: "rfid", label: "RFID" },
          { id: "group", label: "Group RFID" },
        ]}
        clearKeys={[
          "query",
          "name",
          "user_id",
          "rfid_code",
          "parent_rfid_id",
          "group_name",
          "sort_by",
          "sort_order",
        ]}
      />
      {tab === "group" ? (
        <RFIDGroupTab
          records={groups}
          organizations={currentOptions.organizations}
          defaultOrganizationCode={currentOptions.defaultOrganizationCode}
          pagination={pagination}
          loading={loading}
          loadError={loadError}
          onLoad={loadGroup}
          onCreate={createGroup}
          onUpdate={updateGroup}
          onDelete={removeGroup}
          onRefresh={refresh}
        />
      ) : (
        <RFIDCardTab
          records={cards}
          groups={currentOptions.groups}
          options={currentOptions}
          pagination={pagination}
          loading={loading}
          loadError={loadError}
          onLoad={loadCard}
          onCreate={createCard}
          onUpdate={updateCard}
          onDelete={removeCard}
          onRefresh={refresh}
        />
      )}
      {toast && (
        <div
          role={toast.kind === "error" ? "alert" : "status"}
          aria-live={toast.kind === "error" ? "assertive" : "polite"}
          className={`fixed right-5 bottom-5 z-[100] flex max-w-md items-start gap-4 rounded-xl border px-4 py-3 shadow-2xl ${toast.kind === "error" ? "border-destructive/60 bg-background text-destructive" : "border-emerald-500/40 bg-background text-emerald-400"}`}
        >
          <p className="text-sm font-medium">{toast.message}</p>
          <button className="ml-auto text-muted-foreground" onClick={() => setToast(undefined)} aria-label="Dismiss notification">×</button>
        </div>
      )}
    </>
  );
}
