import { useCallback, useEffect, useState } from 'react';
import { getErrorSummary, getSikshyaApi, SIKSHYA_ENDPOINTS } from '../api';
import { EmbeddableShell } from '../components/shared/EmbeddableShell';
import { ApiErrorPanel } from '../components/shared/ApiErrorPanel';
import { ListPanel } from '../components/shared/list/ListPanel';
import { ListEmptyState } from '../components/shared/list/ListEmptyState';
import { StatusBadge } from '../components/shared/list/StatusBadge';
import { ButtonPrimary } from '../components/shared/buttons';
import { RowActionsMenu, type RowActionItem } from '../components/shared/list/RowActionsMenu';
import { Modal } from '../components/shared/Modal';
import { BulkActionsBar } from '../components/shared/list/BulkActionsBar';
import { appViewHref } from '../lib/appUrl';
import { formatPostDate } from '../lib/formatPostDate';
import { useAsyncData } from '../hooks/useAsyncData';
import { useAdminRouting } from '../lib/adminRouting';
import { useSikshyaDialog } from '../components/shared/SikshyaDialogContext';
import type { SikshyaReactConfig } from '../types';
import { __ } from '../lib/i18n';

type PaymentRow = {
  id: number;
  user_id: number;
  course_id: number;
  amount: number;
  currency: string;
  payment_method: string;
  transaction_id: string;
  status: string;
  charge_kind?: string;
  payment_date: string;
  payer_name: string;
  payer_email: string;
  course_title: string;
};

type ListResponse = {
  success?: boolean;
  payments?: PaymentRow[];
  total?: number;
  pages?: number;
  page?: number;
  per_page?: number;
  table_missing?: boolean;
};

export function PaymentsPage(props: { config: SikshyaReactConfig; title: string; embedded?: boolean }) {
  const { config, title, embedded } = props;
  const adminBase = config.adminUrl.replace(/\/?$/, '/');
  const { navigateView } = useAdminRouting();
  const dialog = useSikshyaDialog();
  const [page, setPage] = useState(1);
  const [statusFilter, setStatusFilter] = useState('');
  const [chargeKindFilter, setChargeKindFilter] = useState('');
  const [editOpen, setEditOpen] = useState(false);
  const [editId, setEditId] = useState<number | null>(null);
  const [editStatus, setEditStatus] = useState('pending');
  const [saving, setSaving] = useState(false);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [bulkAction, setBulkAction] = useState('');
  const [bulkBusy, setBulkBusy] = useState(false);

  useEffect(() => {
    setPage(1);
  }, [statusFilter, chargeKindFilter]);

  const loader = useCallback(async () => {
    const q = new URLSearchParams({ page: String(page), per_page: '30' });
    if (statusFilter) {
      q.set('status', statusFilter);
    }
    if (chargeKindFilter) {
      q.set('charge_kind', chargeKindFilter);
    }
    return getSikshyaApi().get<ListResponse>(`${SIKSHYA_ENDPOINTS.admin.payments}?${q.toString()}`);
  }, [page, statusFilter, chargeKindFilter]);

  const { loading, data, error, refetch } = useAsyncData(loader, [page, statusFilter, chargeKindFilter]);

  const rows = data?.payments ?? [];
  const total = data?.total ?? 0;
  const pages = data?.pages ?? 0;
  const tableMissing = Boolean(data?.table_missing);

  useEffect(() => {
    // Clear selection on page/filter changes so bulk actions never surprise the admin.
    setSelectedIds([]);
    setBulkAction('');
  }, [page, statusFilter, chargeKindFilter]);

  const toggleAll = (checked: boolean) => {
    setSelectedIds(checked ? rows.map((r) => r.id) : []);
  };

  const toggleOne = (id: number, checked: boolean) => {
    setSelectedIds((prev) => {
      const s = new Set(prev);
      if (checked) s.add(id);
      else s.delete(id);
      return Array.from(s);
    });
  };

  const applyBulk = async () => {
    if (bulkBusy || selectedIds.length === 0 || !bulkAction) return;
    if (bulkAction === 'delete') {
      const ok = await dialog.confirm({
        title: `Delete ${selectedIds.length} payment(s)?`,
        message: __('This permanently removes the payment records. This cannot be undone.', 'sikshya'),
        confirmLabel: __('Delete', 'sikshya'),
        variant: 'danger',
      });
      if (!ok) return;
    }
    setBulkBusy(true);
    try {
      if (bulkAction.startsWith('status:')) {
        const st = bulkAction.replace(/^status:/, '');
        await getSikshyaApi().post(SIKSHYA_ENDPOINTS.admin.paymentsBulk, {
          action: 'status',
          status: st,
          ids: selectedIds,
        });
      } else if (bulkAction === 'delete') {
        await getSikshyaApi().post(SIKSHYA_ENDPOINTS.admin.paymentsBulk, { action: 'delete', ids: selectedIds });
      }
      setSelectedIds([]);
      setBulkAction('');
      await refetch();
    } catch (err) {
      void dialog.alert({ title: __('Something went wrong', 'sikshya'), message: getErrorSummary(err) });
    } finally {
      setBulkBusy(false);
    }
  };

  const openEdit = (r: PaymentRow) => {
    setEditId(r.id);
    setEditStatus(r.status || 'pending');
    setEditOpen(true);
  };

  return (
    <EmbeddableShell
      embedded={embedded}
      config={config}
      title={title}
      subtitle={__('Checkout charges and automated subscription renewals (when the payments table is installed)', 'sikshya')}
      pageActions={
        <ButtonPrimary type="button" disabled={loading} onClick={() => refetch()}>
          Refresh
        </ButtonPrimary>
      }
    >
      {error ? (
        <div className="mb-4">
          <ApiErrorPanel error={error} title={__('Could not load payments', 'sikshya')} onRetry={() => refetch()} />
        </div>
      ) : null}

      {tableMissing ? (
        <div className="mb-4 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950 dark:border-amber-900/50 dark:bg-amber-950/35 dark:text-amber-100">
          The payments database table is not installed yet. Payments will appear here after migrations and successful
          checkouts.
        </div>
      ) : null}

      <Modal
        open={editOpen}
        title={editId ? `Change payment status (#${editId})` : 'Change payment status'}
        description={__('Update the payment record status.', 'sikshya')}
        size="lg"
        onClose={() => {
          if (!saving) setEditOpen(false);
        }}
        footer={
          <div className="flex items-center justify-end gap-2">
            <button
              type="button"
              className="rounded-lg border border-slate-200 px-3 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50 disabled:opacity-50 dark:border-slate-700 dark:text-slate-200 dark:hover:bg-slate-800"
              disabled={saving}
              onClick={() => setEditOpen(false)}
            >
              Cancel
            </button>
            <ButtonPrimary
              type="button"
              disabled={saving || !editId}
              onClick={async () => {
                if (!editId) return;
                setSaving(true);
                try {
                  await getSikshyaApi().patch<{ ok?: boolean; message?: string }>(
                    SIKSHYA_ENDPOINTS.admin.paymentUpdate(editId),
                    { status: editStatus }
                  );
                  setEditOpen(false);
                  await refetch();
                } catch (err) {
                  void dialog.alert({ title: __('Something went wrong', 'sikshya'), message: getErrorSummary(err) });
                } finally {
                  setSaving(false);
                }
              }}
            >
              {saving ? __('Saving…', 'sikshya') : __('Save', 'sikshya')}
            </ButtonPrimary>
          </div>
        }
      >
        <label className="block text-sm text-slate-700 dark:text-slate-200">
          Status
          <select
            className="mt-1 block w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-sm text-slate-900 placeholder:text-slate-400 focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-white dark:placeholder:text-slate-500"
            value={editStatus}
            onChange={(e) => setEditStatus(e.target.value)}
            disabled={saving}
          >
            <option value="pending">{__('pending', 'sikshya')}</option>
            <option value="completed">{__('completed', 'sikshya')}</option>
            <option value="failed">{__('failed', 'sikshya')}</option>
            <option value="refunded">{__('refunded', 'sikshya')}</option>
          </select>
        </label>
      </Modal>

      <ListPanel>
        {tableMissing ? (
          <ListEmptyState
            title={__('No payments', 'sikshya')}
            description={__('The payments database table is not installed yet.', 'sikshya')}
          />
        ) : (
          <>
            <div className="flex flex-wrap items-center justify-between gap-3 border-b border-slate-100 px-5 py-4 dark:border-slate-800">
              <BulkActionsBar
                disabled={loading}
                selectedCount={selectedIds.length}
                value={bulkAction}
                onChange={setBulkAction}
                onApply={() => void applyBulk()}
                applyBusy={bulkBusy}
                trashMode={false}
                customOptions={[
                  { value: 'delete', label: 'Delete permanently' },
                  { value: 'status:pending', label: 'Mark pending' },
                  { value: 'status:completed', label: 'Mark completed' },
                  { value: 'status:failed', label: 'Mark failed' },
                  { value: 'status:refunded', label: 'Mark refunded' },
                ]}
                selectId="payments-bulk"
              />
              <div className="text-xs text-slate-500 dark:text-slate-400">
                {selectedIds.length > 0 ? `${selectedIds.length} selected` : ''}
              </div>
            </div>
            <div className="flex flex-wrap items-end gap-3 border-b border-slate-100 px-5 py-4 dark:border-slate-800">
              <label className="text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">
                Status
                <select
                  className="mt-1 block min-w-[9rem] rounded-xl border border-slate-200 bg-white px-2 py-2 text-sm font-medium text-slate-800 focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100"
                  value={statusFilter}
                  onChange={(e) => setStatusFilter(e.target.value)}
                  disabled={loading}
                >
                  <option value="">{__('All', 'sikshya')}</option>
                  <option value="pending">{__('Pending', 'sikshya')}</option>
                  <option value="completed">{__('Completed', 'sikshya')}</option>
                  <option value="failed">{__('Failed', 'sikshya')}</option>
                  <option value="refunded">{__('Refunded', 'sikshya')}</option>
                </select>
              </label>
              <label className="text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400">
                Charge type
                <select
                  className="mt-1 block min-w-[9rem] rounded-xl border border-slate-200 bg-white px-2 py-2 text-sm font-medium text-slate-800 focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-500/20 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-600 dark:bg-slate-800 dark:text-slate-100"
                  value={chargeKindFilter}
                  onChange={(e) => setChargeKindFilter(e.target.value)}
                  disabled={loading}
                >
                  <option value="">{__('All', 'sikshya')}</option>
                  <option value="checkout">{__('Checkout', 'sikshya')}</option>
                  <option value="renewal">{__('Renewal', 'sikshya')}</option>
                </select>
              </label>
            </div>
            <div className="overflow-x-auto">
              <table className="min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800">
                <thead className="bg-slate-50/80 text-left text-xs font-semibold uppercase tracking-wide text-slate-500 dark:bg-slate-800/80 dark:text-slate-400">
                  <tr>
                    <th className="w-10 px-5 py-3.5">
                      <input
                        type="checkbox"
                        aria-label={__('Select all payments on this page', 'sikshya')}
                        disabled={loading || rows.length === 0}
                        checked={rows.length > 0 && selectedIds.length === rows.length}
                        onChange={(e) => toggleAll(e.target.checked)}
                      />
                    </th>
                    <th className="px-5 py-3.5">{__('Date', 'sikshya')}</th>
                    <th className="px-5 py-3.5">{__('Payer', 'sikshya')}</th>
                    <th className="px-5 py-3.5">{__('Course', 'sikshya')}</th>
                    <th className="px-5 py-3.5">{__('Amount', 'sikshya')}</th>
                    <th className="px-5 py-3.5">{__('Status', 'sikshya')}</th>
                    <th className="px-5 py-3.5 text-right">{__('Actions', 'sikshya')}</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100 dark:divide-slate-800">
                  {loading ? (
                    <tr>
                      <td colSpan={7} className="px-5 py-12 text-center text-sm text-slate-500 dark:text-slate-400">
                        Loading payments…
                      </td>
                    </tr>
                  ) : rows.length === 0 ? (
                    <tr>
                      <td colSpan={7} className="px-5 py-12 text-center text-sm text-slate-600 dark:text-slate-400">
                        {statusFilter || chargeKindFilter
                          ? 'No records match the current filters.'
                          : 'Completed checkouts and renewal charges will list here for auditing and support.'}
                      </td>
                    </tr>
                  ) : (
                  rows.map((r) => (
                    <tr key={r.id} className="bg-white dark:bg-slate-900">
                      <td className="px-5 py-3.5">
                        <input
                          type="checkbox"
                          aria-label={`Select payment #${r.id}`}
                          checked={selectedIds.includes(r.id)}
                          onChange={(e) => toggleOne(r.id, e.target.checked)}
                        />
                      </td>
                      <td className="whitespace-nowrap px-5 py-3.5 text-slate-600 dark:text-slate-400">
                        {formatPostDate(r.payment_date)}
                        <div className="mt-1 text-xs font-semibold text-brand-600 dark:text-brand-400">
                          <button
                            type="button"
                            className="text-left hover:underline"
                            onClick={(e) => {
                              e.preventDefault();
                              e.stopPropagation();
                              navigateView('payment', { id: String(r.id) });
                            }}
                            title={__('Open payment details', 'sikshya')}
                          >
                            Payment #{r.id}
                          </button>
                        </div>
                        {r.transaction_id ? (
                          <div className="mt-1 truncate font-mono text-xs text-slate-500 dark:text-slate-400">
                            <button
                              type="button"
                              className="hover:underline"
                              onClick={(e) => {
                                e.preventDefault();
                                e.stopPropagation();
                                navigateView('payment', { id: String(r.id) });
                              }}
                              title={__('Open payment details', 'sikshya')}
                            >
                              {r.transaction_id}
                            </button>
                          </div>
                        ) : null}
                      </td>
                      <td className="px-5 py-3.5">
                        <a
                          href={`${adminBase}user-edit.php?user_id=${r.user_id}`}
                          className="font-semibold text-brand-600 hover:text-brand-800 dark:text-brand-400 dark:hover:text-brand-300"
                          onClick={(e) => e.stopPropagation()}
                        >
                          {r.payer_name || `User #${r.user_id}`}
                        </a>
                        <div className="text-xs text-slate-500 dark:text-slate-400">{r.payer_email || '—'}</div>
                      </td>
                      <td className="px-5 py-3.5">
                        {r.course_id > 0 ? (
                          <a
                            href={appViewHref(config, 'add-course', { course_id: String(r.course_id) })}
                            className="font-medium text-brand-600 hover:text-brand-800 dark:text-brand-400 dark:hover:text-brand-300"
                            onClick={(e) => e.stopPropagation()}
                          >
                            {r.course_title || `Course #${r.course_id}`}
                          </a>
                        ) : (r.charge_kind || '').toLowerCase() === 'renewal' ? (
                          <span className="font-medium text-slate-700 dark:text-slate-200">{__('Subscription renewal', 'sikshya')}</span>
                        ) : (
                          '—'
                        )}
                      </td>
                      <td className="whitespace-nowrap px-5 py-3.5 font-medium tabular-nums text-slate-800 dark:text-slate-200">
                        {r.amount.toFixed(2)} {r.currency || ''}
                      </td>
                      <td className="px-5 py-3.5">
                        <StatusBadge status={r.status} />
                        {(r.charge_kind || '').toLowerCase() === 'renewal' ? (
                          <div className="mt-1">
                            <StatusBadge tone="brand" label={__('Renewal', 'sikshya')} size="xs" />
                          </div>
                        ) : null}
                      </td>
                      <td className="px-5 py-3.5 text-right">
                        <div onClick={(e) => e.stopPropagation()} className="inline-flex">
                          {(() => {
                            const items: RowActionItem[] = [
                              {
                                key: 'view',
                                label: 'View details',
                                onClick: () => navigateView('payment', { id: String(r.id) }),
                              },
                              {
                                key: 'status',
                                label: 'Change status',
                                onClick: () => openEdit(r),
                              },
                              {
                                key: 'delete',
                                label: 'Delete',
                                danger: true,
                                onClick: async () => {
                                  const ok = await dialog.confirm({
                                    title: `Delete payment #${r.id}?`,
                                    message: __('This permanently removes the payment record. This cannot be undone.', 'sikshya'),
                                    confirmLabel: __('Delete', 'sikshya'),
                                    variant: 'danger',
                                  });
                                  if (!ok) return;
                                  try {
                                    await getSikshyaApi().delete<{ ok?: boolean; message?: string }>(
                                      SIKSHYA_ENDPOINTS.admin.payment(r.id)
                                    );
                                    await refetch();
                                  } catch (err) {
                                    void dialog.alert({ title: __('Something went wrong', 'sikshya'), message: getErrorSummary(err) });
                                  }
                                },
                              },
                            ];
                            return <RowActionsMenu items={items} ariaLabel={`Payment actions for #${r.id}`} />;
                          })()}
                        </div>
                      </td>
                    </tr>
                  )))}
                </tbody>
              </table>
            </div>
            {!loading && pages > 1 ? (
              <div className="flex flex-wrap items-center justify-between gap-3 border-t border-slate-100 px-5 py-4 dark:border-slate-800">
                <p className="text-xs text-slate-500 dark:text-slate-400">
                  Page {page} of {pages} · {total} total
                </p>
                <div className="flex gap-2">
                  <button
                    type="button"
                    disabled={page <= 1}
                    onClick={() => setPage((p) => Math.max(1, p - 1))}
                    className="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium disabled:opacity-40 dark:border-slate-600 dark:bg-slate-800"
                  >
                    Previous
                  </button>
                  <button
                    type="button"
                    disabled={page >= pages}
                    onClick={() => setPage((p) => p + 1)}
                    className="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-sm font-medium disabled:opacity-40 dark:border-slate-600 dark:bg-slate-800"
                  >
                    Next
                  </button>
                </div>
              </div>
            ) : null}
          </>
        )}
      </ListPanel>
    </EmbeddableShell>
  );
}
