"use client";

import { ChevronLeft, ChevronRight, ChevronDown } from "lucide-react";
import moment from "moment";
import { useState } from "react";

import { useGetTransactionListQuery } from "@/api/transaction.api";
import { ITransaction } from "@/api/types/transaction";
import { SUBSCRIPTION_STATUS } from "@/api/constant";
import { useAppSelector } from "@/redux/hooks";
import ErrorCard from "@/components/common/ErrorCard";

const PER_PAGE_OPTIONS = [10, 20, 50];

const getStatusLabel = (status: number): string => {
  switch (status) {
    case SUBSCRIPTION_STATUS.ACTIVE:
      return "Success";
    case SUBSCRIPTION_STATUS.PENDING:
      return "Pending";
    case SUBSCRIPTION_STATUS.DUE:
      return "Due";
    case SUBSCRIPTION_STATUS.CANCELLED:
      return "Cancelled";
    case SUBSCRIPTION_STATUS.FAILED:
      return "Failed";
    default:
      return "Unknown";
  }
};

const getStatusClass = (status: number): string => {
  switch (status) {
    case SUBSCRIPTION_STATUS.ACTIVE:
      return "text-success";
    case SUBSCRIPTION_STATUS.PENDING:
    case SUBSCRIPTION_STATUS.DUE:
      return "text-blue-pending";
    case SUBSCRIPTION_STATUS.CANCELLED:
    case SUBSCRIPTION_STATUS.FAILED:
      return "text-error";
    default:
      return "text-gray-500";
  }
};

const formatOrderId = (txn: ITransaction): string =>
  txn.externalOrderId
    ? `#${txn.externalOrderId}`
    : txn.externalPaymentId
      ? `#${txn.externalPaymentId}`
      : `#${txn.id}`;

// Only two currencies are supported — show the symbol rather than the code.
const currencySymbol = (currency?: string | null): string => {
  switch ((currency ?? "").toUpperCase()) {
    case "INR":
      return "₹";
    case "USD":
      return "$";
    default:
      return currency ?? "";
  }
};

const formatAmount = (txn: ITransaction): string =>
  `${currencySymbol(txn.currency)}${txn.amount}`;

const formatPlan = (txn: ITransaction): string => txn.planData?.name ?? "—";

const formatDate = (value: string | null): string =>
  value ? moment(value).format("MMM D, YYYY") : "—";

const PaymentHistorySection = () => {
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(20);
  const { user } = useAppSelector((state) => state.auth);

  const { data, isLoading, isFetching, error, refetch } =
    useGetTransactionListQuery(
      {
        page,
        perPage,
        transactionType: "subscription",
        userId: user?.id,
      },
      { skip: !user?.id },
    );

  const transactions = data?.data ?? [];
  const totalRecords = data?.totalRecords ?? 0;
  const totalPages = data?.totalPages ?? 0;
  const hasPrev = page > 1;
  const hasNext = totalPages > 0 && page < totalPages;

  const rangeStart = totalRecords === 0 ? 0 : (page - 1) * perPage + 1;
  const rangeEnd = Math.min(page * perPage, totalRecords);

  const handlePerPageChange = (value: number) => {
    setPerPage(value);
    setPage(1);
  };

  return (
    <div className="flex flex-col w-full">
      <h2 className="text-black font-semibold text-[24px] leading-[1.2] tracking-[-0.24px]">
        Payment History
      </h2>

      {isLoading ? (
        <div className="bg-white border border-brand-border-card rounded-[14px] shadow-sm mt-[30px] py-12 flex justify-center">
          <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-light" />
        </div>
      ) : error ? (
        <div className="mt-[30px]">
          <ErrorCard
            message="Failed to load payment history. Please try again."
            onRetry={() => refetch()}
          />
        </div>
      ) : transactions.length === 0 ? (
        <div className="bg-white border border-brand-border-card rounded-[14px] shadow-sm mt-[30px] py-12 px-4 text-center text-gray-500 text-[14px]">
          No payments yet.
        </div>
      ) : (
        <>
          {/* Table — lg and up */}
          <div className="hidden lg:block bg-white border border-brand-border-card rounded-[14px] overflow-x-auto shadow-sm mt-[30px]">
            <table className="w-full min-w-[800px] text-left border-collapse">
              <thead>
                <tr className="border-b border-gray-275">
                  <th className="px-4 py-3 md:px-8 md:py-5 text-black font-semibold text-[16px] md:text-[20px] leading-[1.2] tracking-[-0.2px]">
                    Order ID
                  </th>
                  <th className="px-4 py-3 md:px-8 md:py-5 text-black font-semibold text-[16px] md:text-[20px] leading-[1.2] tracking-[-0.2px]">
                    Plan
                  </th>
                  <th className="px-4 py-3 md:px-8 md:py-5 text-black font-semibold text-[16px] md:text-[20px] leading-[1.2] tracking-[-0.2px]">
                    Date
                  </th>
                  <th className="px-4 py-3 md:px-8 md:py-5 text-black font-semibold text-[16px] md:text-[20px] leading-[1.2] tracking-[-0.2px]">
                    Amount
                  </th>
                  <th className="px-4 py-3 md:px-8 md:py-5 text-black font-semibold text-[16px] md:text-[20px] leading-[1.2] tracking-[-0.2px] text-right">
                    Status
                  </th>
                </tr>
              </thead>
              <tbody>
                {transactions.map((txn, idx) => (
                  <tr
                    key={txn.id}
                    className={`${
                      idx < transactions.length - 1
                        ? "border-b border-gray-125"
                        : ""
                    } hover:bg-gray-100`}
                  >
                    <td className="px-4 py-3 md:px-8 md:py-5 text-black font-medium text-[14px] md:text-[18px] leading-[1.01] whitespace-nowrap">
                      {formatOrderId(txn)}
                    </td>
                    <td className="px-4 py-3 md:px-8 md:py-5 text-blue-muted text-[13px] md:text-[16px] font-normal leading-[1.2]">
                      {formatPlan(txn)}
                    </td>
                    <td className="px-4 py-3 md:px-8 md:py-5 text-blue-muted text-[13px] md:text-[16px] font-normal leading-[1.2]">
                      {formatDate(txn.paidAt ?? txn.createdAt)}
                    </td>
                    <td className="px-4 py-3 md:px-8 md:py-5 text-blue-muted text-[13px] md:text-[16px] font-normal leading-[1.2]">
                      {formatAmount(txn)}
                    </td>
                    <td className="px-4 py-3 md:px-8 md:py-5 text-right">
                      <span
                        className={`text-[12px] md:text-[14px] font-medium ${getStatusClass(txn.status)}`}
                      >
                        {getStatusLabel(txn.status)}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          {/* Cards — below lg, easier to read on small screens */}
          <div className="lg:hidden flex flex-col gap-3 mt-[30px]">
            {transactions.map((txn) => (
              <div
                key={txn.id}
                className="bg-white border border-brand-border-card rounded-[14px] p-4 shadow-sm flex flex-col gap-3"
              >
                <div className="flex items-center justify-between gap-3">
                  <span className="text-black font-semibold text-[15px] leading-tight break-all">
                    {formatOrderId(txn)}
                  </span>
                  <span
                    className={`text-[12px] font-semibold shrink-0 ${getStatusClass(txn.status)}`}
                  >
                    {getStatusLabel(txn.status)}
                  </span>
                </div>

                <div className="h-px bg-gray-125" />

                <div className="flex items-center justify-between gap-3 text-[13px]">
                  <span className="text-gray-500">Plan</span>
                  <span className="text-blue-muted font-medium text-right">
                    {formatPlan(txn)}
                  </span>
                </div>
                <div className="flex items-center justify-between gap-3 text-[13px]">
                  <span className="text-gray-500">Date</span>
                  <span className="text-blue-muted font-medium text-right">
                    {formatDate(txn.paidAt ?? txn.createdAt)}
                  </span>
                </div>
                <div className="flex items-center justify-between gap-3 text-[13px]">
                  <span className="text-gray-500">Amount</span>
                  <span className="text-blue-muted font-medium text-right">
                    {formatAmount(txn)}
                  </span>
                </div>
              </div>
            ))}
          </div>
        </>
      )}

      {/* Pagination — only when there's more than one page worth of records */}
      {totalRecords > 20 && (
        <div className="flex flex-col sm:flex-row items-center justify-between gap-4 mt-4">
          <div className="flex items-center gap-2">
            <div className="relative">
              <select
                value={perPage}
                onChange={(e) => handlePerPageChange(Number(e.target.value))}
                disabled={isFetching}
                className="appearance-none bg-white border border-brand-border-card pl-3 pr-8 py-1.5 rounded-md text-[14px] text-gray-900 cursor-pointer hover:bg-gray-50 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
              >
                {PER_PAGE_OPTIONS.map((opt) => (
                  <option key={opt} value={opt}>
                    {opt}
                  </option>
                ))}
              </select>
              <ChevronDown
                size={14}
                className="text-gray-550 absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none"
              />
            </div>
            <span className="text-black text-[14px] md:text-[18px] font-medium leading-[1.01]">
              per page
            </span>
          </div>

          <div className="flex items-center gap-4 sm:gap-6">
            <span className="text-black text-[13px] md:text-[15px] font-medium leading-[1.01]">
              {totalRecords === 0
                ? "0 results"
                : `${rangeStart}-${rangeEnd} of ${totalRecords}`}
            </span>

            <div className="flex items-center gap-2">
              <button
                type="button"
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={!hasPrev || isFetching}
                aria-label="Previous page"
                className="w-8 h-8 flex items-center justify-center border border-brand-border-card rounded-md text-gray-550 hover:bg-gray-50 hover:text-gray-900 transition-all disabled:opacity-30 disabled:cursor-not-allowed"
              >
                <ChevronLeft size={18} />
              </button>
              <button
                type="button"
                onClick={() => setPage((p) => p + 1)}
                disabled={!hasNext || isFetching}
                aria-label="Next page"
                className="w-8 h-8 flex items-center justify-center border border-brand-border-card rounded-md text-gray-550 hover:bg-gray-50 hover:text-gray-900 transition-all disabled:opacity-30 disabled:cursor-not-allowed"
              >
                <ChevronRight size={18} />
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default PaymentHistorySection;
