// src/app/admin/(protected)/schedule-requests/page.tsx
"use client";

import { useEffect, useMemo, useState } from "react";
import { toast } from "react-toastify";
import axiosInstance from "@/lib/axiosInstance";
import { fmt12 } from "@/lib/timeslot-utils";
import { ColumnDef } from "@tanstack/react-table";
import DataTable from "@/components/common/DataTable";

interface ChangeRequest {
  id: number;
  booking_id: number | null;
  current_booking_date: string | null;
  current_start_time: string | null;
  current_end_time: string | null;
  requested_date: string;
  requested_start_time: string;
  requested_end_time: string;
  reason: string | null;
  status: string;
  admin_note: string | null;
  created_at: string;
  schedule_bookings: {
    booking_date: string;
    time_slots: { start_time: string; end_time: string };
    student_schedules: {
      students: { id: number; name: string; email: string; contact: string };
    };
  } | null;
}

const statusBadgeClass = (status: string) => {
  switch (status) {
    case "approved": return "bg-success";
    case "rejected": return "bg-danger";
    default: return "bg-warning text-dark";
  }
};

const TABS = [
  { key: "pending", label: "Pending" },
  { key: "approved", label: "Approved" },
  { key: "rejected", label: "Rejected" },
  { key: "", label: "All" },
];

export default function AdminScheduleRequestsPage() {
  const [requests, setRequests] = useState<ChangeRequest[]>([]);
  const [loading, setLoading] = useState(true);
  const [activeTab, setActiveTab] = useState("pending");

  // per-row loading state, e.g. { "12-approve": true, "12-reject": true }
  const [rowLoading, setRowLoading] = useState<Record<string, boolean>>({});

  // reject modal state
  const [rejectTarget, setRejectTarget] = useState<ChangeRequest | null>(null);
  const [rejectNote, setRejectNote] = useState("");

  useEffect(() => {
    loadRequests();
  }, [activeTab]);

  const loadRequests = async () => {
    setLoading(true);
    try {
      const { data } = await axiosInstance.get("/admin/schedule-requests", {
        params: activeTab ? { status: activeTab } : {},
      });
      setRequests(data.data);
    } catch (err) {
      toast.error("Failed to load schedule requests");
    } finally {
      setLoading(false);
    }
  };

  const setRowKeyLoading = (id: number, action: string, val: boolean) =>
    setRowLoading((prev) => ({ ...prev, [`${id}-${action}`]: val }));

  const handleApprove = async (req: ChangeRequest) => {
    setRowKeyLoading(req.id, "approve", true);
    try {
      await axiosInstance.patch(`/admin/schedule-requests/${req.id}`, { action: "approve" });
      toast.success("Request approved and schedule updated");
      await loadRequests();
    } catch (err: any) {
      toast.error(err?.response?.data?.error ?? "Failed to approve request");
    } finally {
      setRowKeyLoading(req.id, "approve", false);
    }
  };

  const openRejectModal = (req: ChangeRequest) => {
    setRejectTarget(req);
    setRejectNote("");
  };

  const handleReject = async () => {
    if (!rejectTarget) return;
    setRowKeyLoading(rejectTarget.id, "reject", true);
    try {
      await axiosInstance.patch(`/admin/schedule-requests/${rejectTarget.id}`, {
        action: "reject",
        admin_note: rejectNote.trim() || undefined,
      });
      toast.success("Request rejected");
      setRejectTarget(null);
      await loadRequests();
    } catch (err: any) {
      toast.error(err?.response?.data?.error ?? "Failed to reject request");
    } finally {
      setRowKeyLoading(rejectTarget.id, "reject", false);
    }
  };

  const columns = useMemo<ColumnDef<ChangeRequest>[]>(
    () => [
      {
        header: "Student",
        cell: ({ row }) => {
          const s = row.original.schedule_bookings?.student_schedules.students;
          return s ? (
            <span className="small">
              {s.name}
              <br />
              <span className="text-muted">{s.email}</span>
            </span>
          ) : (
            "—"
          );
        },
      },
      {
        header: "From",
        cell: ({ row }) => {
          const r = row.original;
          const dateLabel = r.current_booking_date ? r.current_booking_date.slice(0, 10) : "—";

          if (!r.current_start_time || !r.current_end_time) {
            return <span className="small text-muted">{dateLabel}</span>;
          }

          return (
            <span className="small">
              {dateLabel}
              <br />
              {fmt12(r.current_start_time)} - {fmt12(r.current_end_time)}
            </span>
          );
        },
      },
      {
        header: "Requested",
        cell: ({ row }) => {
          const r = row.original;
          return (
            <span className="small">
              {r.requested_date.slice(0, 10)}
              <br />
              {fmt12(r.requested_start_time)} - {fmt12(r.requested_end_time)}
            </span>
          );
        },
      },
      {
        header: "Reason",
        accessorFn: (r) => r.reason || "—",
        id: "reason",
      },
      {
        header: "Status",
        cell: ({ row }) => (
          <span className={`badge ${statusBadgeClass(row.original.status)}`}>{row.original.status}</span>
        ),
      },
      {
        header: "Admin note",
        accessorFn: (r) => r.admin_note || "—",
        id: "admin_note",
      },
      {
        header: "Actions",
        cell: ({ row }) => {
          const r = row.original;
          if (r.status !== "pending") return null;

          const approving = !!rowLoading[`${r.id}-approve`];
          const rejecting = !!rowLoading[`${r.id}-reject`];

          return (
            <div className="d-flex gap-2">
              <button
                className="btn btn-sm btn-success"
                disabled={approving || rejecting}
                onClick={() => handleApprove(r)}
              >
                {approving && <span className="spinner-border spinner-border-sm me-1" />}
                Approve
              </button>
              <button
                className="btn btn-sm btn-outline-danger"
                disabled={approving || rejecting}
                onClick={() => openRejectModal(r)}
              >
                Reject
              </button>
            </div>
          );
        },
      },
    ],
    [rowLoading]
  );

  return (
    <div className="admin-page-wrapper">
      <div className="admin-page-header mb-2 mb-md-4">
        <h2 className="admin-page-title">Schedule Change Requests</h2>
        <p className="admin-page-subtitle">Review and act on student-submitted schedule changes</p>
      </div>

      <ul className="nav nav-tabs mb-3">
        {TABS.map((t) => (
          <li className="nav-item" key={t.key}>
            <button
              className={`nav-link ${activeTab === t.key ? "active" : ""}`}
              onClick={() => setActiveTab(t.key)}
            >
              {t.label}
            </button>
          </li>
        ))}
      </ul>

      <div className="p-0">
        {loading ? (
          <p className="text-muted small mb-0">Loading...</p>
        ) : requests.length === 0 ? (
          <p className="text-muted small mb-0">No requests in this view.</p>
        ) : (
          <DataTable columns={columns} data={requests} />
        )}
      </div>

      {/* Reject confirmation modal */}
      {rejectTarget && (
        <div className="modal d-block" style={{ background: "rgba(0,0,0,0.5)" }} onClick={() => setRejectTarget(null)}>
          <div className="modal-dialog" onClick={(e) => e.stopPropagation()}>
            <div className="modal-content">
              <div className="modal-header">
                <h5 className="modal-title">Reject Request</h5>
                <button className="btn-close" onClick={() => setRejectTarget(null)} />
              </div>
              <div className="modal-body">
                <label className="form-label small">Reason for student (optional)</label>
                <textarea
                  className="form-control form-control-sm"
                  rows={3}
                  value={rejectNote}
                  onChange={(e) => setRejectNote(e.target.value)}
                  placeholder="e.g. Requested slot conflicts with another class"
                />
              </div>
              <div className="modal-footer">
                <button className="btn btn-sm btn-outline-secondary" onClick={() => setRejectTarget(null)}>
                  Cancel
                </button>
                <button
                  className="btn btn-sm btn-danger"
                  disabled={!!rowLoading[`${rejectTarget.id}-reject`]}
                  onClick={handleReject}
                >
                  {rowLoading[`${rejectTarget.id}-reject`] && (
                    <span className="spinner-border spinner-border-sm me-1" />
                  )}
                  Confirm Reject
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}