"use client";

import { Suspense, useState } from "react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { useLang } from "@/context/LanguageContext";
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
import { Alert, Button, Input, Select, Spinner } from "@/components/ui";
import { api } from "@/lib/client";
import { IncrelogLogo } from "@/components/IncrelogLogo";
import { formatBDT, formatDate } from "@/lib/utils";
import { PAYMENT_METHODS } from "@/lib/constants";
import { IconCheck, IconSearch, IconX } from "@/components/icons";
import { PaymentAccountCards, type PublicAccount } from "@/components/PaymentAccountCards";

/* Public application tracking — an institution-side switch (Control Panel)
   enables it. The applicant enters the institution code, the application
   reference received after applying (and by email) plus a proof of identity:
   the phone/email on the application, or the password of the tracking
   account created while applying. Verified applicants see status, queue
   position and fee state — and can submit their fee transaction (gateway +
   TrxID) for the institution to verify. */

interface TrackedApplication {
  reference: string;
  studentName: string;
  className: string | null;
  sessionName: string | null;
  status: string;
  createdAt: string;
  decidedAt: string | null;
  roll: string | null;
  position: number | null;
  totalPending: number;
  fee: {
    amount: number;
    status: string;
    method: string | null;
    txnId: string | null;
    submittedByApplicant: boolean;
  };
}

interface TrackResult {
  application: TrackedApplication;
  institution: { name: string; code: string };
  paymentAccounts: PublicAccount[];
}

/** animated status emblem per application state */
function StatusEmblem({ status }: { status: string }) {
  if (status === "APPROVED") {
    return (
      <span className="ems-track-emblem ems-track-approved">
        <IconCheck className="svg-32" />
      </span>
    );
  }
  if (status === "REJECTED") {
    return (
      <span className="ems-track-emblem ems-track-rejected">
        <IconX className="svg-32" />
      </span>
    );
  }
  return (
    <span className="ems-track-emblem ems-track-pending" aria-hidden="true">
      <svg viewBox="0 0 48 48" width="34" height="34" fill="none">
        <circle className="ems-track-ring" cx="24" cy="24" r="18" stroke="#24695c" strokeWidth="4" strokeLinecap="round" strokeDasharray="80 40" />
        <circle cx="24" cy="24" r="4.5" fill="#24695c" />
      </svg>
    </span>
  );
}

function TrackForm({ onResult }: { onResult: (r: TrackResult, verify: { contact: string; password: string }) => void }) {
  const { t } = useLang();
  const tr = t.trackPage;
  const params = useSearchParams();

  const [code, setCode] = useState(params.get("code")?.toUpperCase() ?? "");
  const [reference, setReference] = useState(params.get("ref")?.toUpperCase() ?? "");
  const [contact, setContact] = useState("");
  const [password, setPassword] = useState("");
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  async function lookup(e: React.FormEvent) {
    e.preventDefault();
    if (loading) return;
    setLoading(true);
    setError("");
    try {
      const res = await api<TrackResult>("/api/public/track", {
        method: "POST",
        body: JSON.stringify({
          code,
          reference,
          verify: { contact: contact.trim() || undefined, password: password || undefined },
        }),
      });
      onResult(res, { contact, password });
    } catch (err) {
      const msg = err instanceof Error ? err.message : "";
      setError(
        msg === "TRACKING_DISABLED" ? tr.errDisabled
          : msg === "INSTITUTION_NOT_FOUND" ? tr.errInstitution
          : msg === "NOT_FOUND" || msg === "BAD_REFERENCE" ? tr.errNotFound
          : msg === "WRONG_VERIFY" ? tr.errVerify
          : t.common.tryAgain
      );
    } finally {
      setLoading(false);
    }
  }

  return (
    <form className="theme-form" onSubmit={lookup}>
      <div className="row g-2">
        <div className="col-12 col-md-6">
          <Input
            label={`${t.auth.institutionCode} *`}
            value={code}
            placeholder="HS-1001"
            onChange={(e) => setCode(e.target.value.toUpperCase())}
          />
        </div>
        <div className="col-12 col-md-6">
          <Input
            label={`${tr.reference} *`}
            value={reference}
            placeholder="APP-00030"
            onChange={(e) => setReference(e.target.value.toUpperCase())}
          />
        </div>
        <div className="col-12 col-md-6">
          <Input
            label={tr.contactLabel}
            placeholder={tr.contactPlaceholder}
            value={contact}
            onChange={(e) => setContact(e.target.value)}
          />
        </div>
        <div className="col-12 col-md-6">
          <Input
            label={tr.passwordLabel}
            type="password"
            autoComplete="current-password"
            placeholder="••••••••"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
        </div>
      </div>
      <p className="ems-fs-11 text-muted mb-3">{tr.verifyHint}</p>
      {error && (
        <div className="mb-3">
          <Alert type="error">{error}</Alert>
        </div>
      )}
      <Button type="submit" className="w-100" loading={loading} disabled={!code.trim() || !reference.trim()}>
        <IconSearch className="svg-16" />
        <span className="ms-1">{tr.lookupButton}</span>
      </Button>
    </form>
  );
}

function TrackResultView({
  result,
  verify,
  onBack,
}: {
  result: TrackResult;
  verify: { contact: string; password: string };
  onBack: () => void;
}) {
  const { t, locale } = useLang();
  const tr = t.trackPage;
  const app = result.application;
  const [method, setMethod] = useState("BKASH");
  const [txnId, setTxnId] = useState("");
  const [account, setAccount] = useState("");
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
  const [submitted, setSubmitted] = useState(app.fee.submittedByApplicant);

  async function submitPayment(e: React.FormEvent) {
    e.preventDefault();
    if (saving) return;
    setSaving(true);
    setMessage(null);
    try {
      await api("/api/public/track", {
        method: "POST",
        body: JSON.stringify({
          action: "submit-payment",
          code: result.institution.code,
          reference: app.reference,
          verify: { contact: verify.contact.trim() || undefined, password: verify.password || undefined },
          method,
          txnId,
          account,
        }),
      });
      setSubmitted(true);
      setTxnId("");
      setMessage({ type: "success", text: tr.paymentSubmitted });
    } catch (err) {
      const msg = err instanceof Error ? err.message : "";
      setMessage({
        type: "error",
        text: msg === "NOT_DUE" || msg === "NO_FEE" ? tr.errNotDue : t.common.tryAgain,
      });
    } finally {
      setSaving(false);
    }
  }

  const statusLabel = t.status[app.status as keyof typeof t.status] ?? app.status;

  return (
    <div>
      {/* status header */}
      <div className="text-center mb-3">
        <StatusEmblem status={app.status} />
        <h4 className="f-w-700 mb-1 mt-2">{statusLabel}</h4>
        <p className="ems-fs-12 text-muted mb-0">
          {tr.refLabel}: <code className="ems-invoice-badge">{app.reference}</code>
        </p>
        <p className="ems-fs-12 text-muted mb-0">
          {result.institution.name} · {formatDate(app.createdAt, locale)}
        </p>
      </div>

      {/* details */}
      <div style={{ border: "1px solid #e6edef", borderRadius: 10, padding: "4px 14px" }}>
        <div className="d-flex justify-content-between gap-3 py-2" style={{ borderBottom: "1px dashed #edf2f0" }}>
          <span className="ems-fs-12 text-muted text-nowrap">{t.portal.admissionsPage.studentName}</span>
          <span className="ems-fs-13 f-w-600 text-end">{app.studentName}</span>
        </div>
        {app.className && (
          <div className="d-flex justify-content-between gap-3 py-2" style={{ borderBottom: "1px dashed #edf2f0" }}>
            <span className="ems-fs-12 text-muted text-nowrap">{t.portal.admissionsPage.applyClass}</span>
            <span className="ems-fs-13 f-w-600 text-end">{app.className}</span>
          </div>
        )}
        {app.sessionName && (
          <div className="d-flex justify-content-between gap-3 py-2" style={{ borderBottom: "1px dashed #edf2f0" }}>
            <span className="ems-fs-12 text-muted text-nowrap">{t.categories.SESSION}</span>
            <span className="ems-fs-13 f-w-600 text-end">{app.sessionName}</span>
          </div>
        )}
        {app.status === "PENDING" && app.position !== null && (
          <div className="d-flex justify-content-between gap-3 py-2" style={{ borderBottom: "1px dashed #edf2f0" }}>
            <span className="ems-fs-12 text-muted text-nowrap">{tr.positionLabel}</span>
            <span className="ems-fs-13 f-w-700 text-end ems-text-teal">
              #{app.position} {tr.positionOf.replace("{n}", String(app.totalPending))}
            </span>
          </div>
        )}
        {app.status === "APPROVED" && app.roll && (
          <div className="d-flex justify-content-between gap-3 py-2" style={{ borderBottom: "1px dashed #edf2f0" }}>
            <span className="ems-fs-12 text-muted text-nowrap">{t.portal.admissionsPage.roll}</span>
            <span className="ems-fs-13 f-w-700 text-end text-success">{app.roll}</span>
          </div>
        )}
        {app.status !== "PENDING" && app.decidedAt && (
          <div className="d-flex justify-content-between gap-3 py-2">
            <span className="ems-fs-12 text-muted text-nowrap">{t.portal.admissionsPage.decidedOn}</span>
            <span className="ems-fs-13 f-w-600 text-end">{formatDate(app.decidedAt, locale)}</span>
          </div>
        )}
      </div>

      {/* application fee */}
      {app.fee.amount > 0 && (
        <div className="mt-3" style={{ border: "1px solid rgba(36,105,92,0.25)", borderRadius: 10, padding: "12px 14px", background: "rgba(36,105,92,0.04)" }}>
          <div className="d-flex justify-content-between align-items-center gap-2 mb-1">
            <p className="f-w-700 ems-fs-13 mb-0 ems-text-teal">
              {t.portal.admissionsPage.feeCol} — {formatBDT(app.fee.amount, locale)}
            </p>
            {app.fee.status === "PAID" ? (
              <span className="badge badge-success">{t.portal.admissionsPage.feePaid}</span>
            ) : app.fee.status === "WAIVED" ? (
              <span className="badge badge-secondary">{t.portal.admissionsPage.feeWaived}</span>
            ) : (
              <span className="badge badge-danger">{t.portal.hrPage.dueLabel}</span>
            )}
          </div>

          {app.fee.status === "PAID" && (
            <p className="ems-fs-12 text-muted mb-0">
              {tr.feeVerifiedNote}
              {app.fee.method && ` · ${t.methods[app.fee.method as keyof typeof t.methods] ?? app.fee.method}`}
            </p>
          )}

          {app.fee.status === "DUE" && (
            <>
              {submitted ? (
                <div className="mt-2">
                  <Alert type="success">{tr.paymentSubmitted}</Alert>
                  {app.fee.txnId && (
                    <p className="ems-fs-12 text-muted mb-0">
                      {t.portal.feesPage.cfTxnId}: <code className="ems-invoice-badge">{app.fee.txnId}</code>
                    </p>
                  )}
                </div>
              ) : (
                <div className="mt-2">
                  <p className="ems-fs-12 text-muted mb-2">{tr.feeWhereHint}</p>
                  <PaymentAccountCards accounts={result.paymentAccounts} />
                  <form className="theme-form mt-2" onSubmit={submitPayment}>
                    <div className="row g-2">
                      <div className="col-12 col-md-6">
                        <Select label={tr.gatewayLabel} value={method} onChange={(e) => setMethod(e.target.value)}>
                          {PAYMENT_METHODS.filter((m) => m !== "CASH").map((m) => (
                            <option key={m} value={m}>
                              {t.methods[m]}
                            </option>
                          ))}
                        </Select>
                      </div>
                      <div className="col-12 col-md-6">
                        <Input
                          label={`${t.portal.feesPage.cfTxnId} *`}
                          placeholder="8N7A1B2C"
                          value={txnId}
                          onChange={(e) => setTxnId(e.target.value)}
                        />
                      </div>
                      <div className="col-12">
                        <Input
                          label={t.portal.feesPage.cfAccount}
                          placeholder="01XXXXXXXXX"
                          inputMode="numeric"
                          value={account}
                          onChange={(e) => setAccount(e.target.value.replace(/\D/g, ""))}
                        />
                      </div>
                    </div>
                    {message && <Alert type={message.type}>{message.text}</Alert>}
                    <Button type="submit" className="w-100" loading={saving} disabled={!txnId.trim()}>
                      <IconCheck className="svg-16" />
                      <span className="ms-1">{tr.submitPayment}</span>
                    </Button>
                  </form>
                </div>
              )}
            </>
          )}
        </div>
      )}

      <div className="text-center mt-3">
        <Button variant="secondary" size="sm" onClick={onBack}>
          {tr.trackAnother}
        </Button>
      </div>
    </div>
  );
}

function TrackPageInner() {
  const { t } = useLang();
  const tr = t.trackPage;
  const [result, setResult] = useState<TrackResult | null>(null);
  const [verify, setVerify] = useState({ contact: "", password: "" });

  return (
    <div className="ems-auth-wrapper ems-apply-page">
      <div className="container-fluid py-3">
        <div className="d-flex justify-content-between align-items-center py-2">
          <Link href="/" className="d-flex align-items-center gap-2 text-decoration-none">
            <IncrelogLogo size={34} />
            <h6 className="mb-0 f-w-800 text-dark">IncrelogEMS</h6>
          </Link>
          <LanguageSwitcher />
        </div>

        <div className="ems-apply-wrap">
          <div
            className="login-form card ems-wizard-card"
            style={{ width: "100%", maxWidth: 620, borderRadius: 12, border: "none", boxShadow: "0 10px 40px rgba(36,105,92,0.12)" }}
          >
            <div className="card-body p-3 p-md-4 d-flex flex-column" style={{ gap: 12, minHeight: 0, flex: "1 1 auto" }}>
              <div className="text-center mb-0">
                <h4 className="f-w-700 mb-1">{tr.title}</h4>
                <h6 className="text-muted f-w-500">{tr.subtitle}</h6>
              </div>

              <div className="ems-wizard-scroll">
                {result ? (
                  <TrackResultView result={result} verify={verify} onBack={() => setResult(null)} />
                ) : (
                  <TrackForm
                    onResult={(r, v) => {
                      setResult(r);
                      setVerify(v);
                    }}
                  />
                )}
              </div>

              <p className="text-center ems-fs-13 mb-0">
                {tr.notAppliedYet}{" "}
                <Link href="/apply" className="ems-text-teal f-w-700 text-decoration-none">
                  {t.applyPage.navLabel}
                </Link>
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default function TrackPage() {
  return (
    <Suspense
      fallback={
        <div className="ems-auth-wrapper">
          <div className="d-flex justify-content-center py-5">
            <Spinner />
          </div>
        </div>
      }
    >
      <TrackPageInner />
    </Suspense>
  );
}
