import { useEffect, useMemo, useRef, useState } from "react";
import { Check, RefreshCw } from "lucide-react";
import type { ApiSettings } from "@govoplan/core-webui";
import { AdminPageLayout, Button, Card, StatusBadge, adminErrorMessage, formatDateTime, i18nMessage, mergeDeltaRows, useDeltaWatermarks } from "@govoplan/core-webui";
import {
  approveConfigurationChangeRequest,
  fetchConfigurationChangesDelta,
  type ConfigurationChangeRecord,
  type ConfigurationChangeRequest } from
"../../api/admin";

const DELTA_KEY = "admin:configuration-changes";

export default function ConfigurationChangesPanel({ settings, canApprove }: {settings: ApiSettings;canApprove: boolean;}) {
  const [requests, setRequests] = useState<ConfigurationChangeRequest[]>([]);
  const [history, setHistory] = useState<ConfigurationChangeRecord[]>([]);
  const requestsRef = useRef<ConfigurationChangeRequest[]>([]);
  const historyRef = useRef<ConfigurationChangeRecord[]>([]);
  const { getDeltaWatermark, setDeltaWatermark, resetDeltaWatermark } = useDeltaWatermarks();
  const [loading, setLoading] = useState(true);
  const [busyId, setBusyId] = useState("");
  const [error, setError] = useState("");
  const [message, setMessage] = useState("");

  async function load() {
    setLoading(true);
    setError("");
    try {
      let nextWatermark = getDeltaWatermark(DELTA_KEY);
      let nextRequests = requestsRef.current;
      let nextHistory = historyRef.current;
      let hasMore = false;
      do {
        const payload = await fetchConfigurationChangesDelta(settings, { since: nextWatermark });
        nextRequests = payload.full ? payload.requests : mergeDeltaRows(nextRequests, payload.requests, payload.deleted, (request) => request.id, { sort: sortConfigurationRequests });
        nextHistory = payload.full ? payload.history : mergeDeltaRows(nextHistory, payload.history, payload.deleted, (record) => record.id, { sort: sortConfigurationHistory });
        nextWatermark = payload.watermark ?? null;
        hasMore = payload.has_more;
      } while (hasMore);
      requestsRef.current = nextRequests;
      historyRef.current = nextHistory;
      setRequests(nextRequests);
      setHistory(nextHistory);
      setDeltaWatermark(DELTA_KEY, nextWatermark);
    } catch (err) {
      setError(adminErrorMessage(err));
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    requestsRef.current = [];
    historyRef.current = [];
    resetDeltaWatermark(DELTA_KEY);
    void load();
  }, [settings.accessToken, settings.apiBaseUrl, resetDeltaWatermark]);

  async function approve(request: ConfigurationChangeRequest) {
    setBusyId(request.id);
    setError("");
    setMessage("");
    try {
      await approveConfigurationChangeRequest(settings, request.id);
      setMessage(i18nMessage("i18n:govoplan-admin.approved_value.52da808b", { value0: request.key }));
      await load();
    } catch (err) {
      setError(adminErrorMessage(err));
    } finally {
      setBusyId("");
    }
  }

  const pending = useMemo(() => requests.filter((item) => item.status !== "applied" && item.status !== "rejected"), [requests]);

  return (
    <AdminPageLayout
      title="i18n:govoplan-admin.configuration_changes.82933bbb"
      description="i18n:govoplan-admin.safety_controlled_configuration_requests_approva.e8259509"
      loading={loading}
      error={error}
      success={message}
      actions={<Button onClick={() => void load()} disabled={loading}><RefreshCw size={16} /> i18n:govoplan-admin.reload.cce71553</Button>}>

      <Card title="i18n:govoplan-admin.requests.f7194e6a">
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>i18n:govoplan-admin.setting.fb449f71</th>
                <th>i18n:govoplan-admin.status.bae7d5be</th>
                <th>i18n:govoplan-admin.requested.c26bf60f</th>
                <th>i18n:govoplan-admin.approvals.deb9d03c</th>
                <th>i18n:govoplan-admin.target.61ad50a9</th>
                <th className="actions">i18n:govoplan-admin.action.97c89a4d</th>
              </tr>
            </thead>
            <tbody>
              {pending.map((request) =>
              <tr key={request.id}>
                  <td><strong>{request.label || request.key}</strong><span className="muted block">{request.key}</span></td>
                  <td><StatusBadge status={statusTone(request.status)} label={request.status} /></td>
                  <td>{formatDateTime(request.requested_at)}</td>
                  <td>{request.approvals.length}</td>
                  <td>{targetLabel(request.target)}</td>
                  <td className="actions">
                    {canApprove && request.status === "pending_approval" &&
                  <Button onClick={() => void approve(request)} disabled={busyId === request.id}><Check size={16} /> i18n:govoplan-admin.approve.7b2c7f14</Button>
                  }
                  </td>
                </tr>
              )}
              {!pending.length && <tr><td colSpan={6} className="muted">i18n:govoplan-admin.no_open_requests.580c95f9</td></tr>}
            </tbody>
          </table>
        </div>
      </Card>

      <Card title="i18n:govoplan-admin.history.90ccd649">
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>i18n:govoplan-admin.version.2da600bf</th>
                <th>i18n:govoplan-admin.setting.fb449f71</th>
                <th>i18n:govoplan-admin.status.bae7d5be</th>
                <th>i18n:govoplan-admin.applied.a3e4a569</th>
                <th>i18n:govoplan-admin.approvers.0e2de1fb</th>
                <th>i18n:govoplan-admin.target.61ad50a9</th>
              </tr>
            </thead>
            <tbody>
              {history.map((record) =>
              <tr key={record.id}>
                  <td>#{record.version}</td>
                  <td><strong>{record.key}</strong><span className="muted block">{record.id}</span></td>
                  <td><StatusBadge status={statusTone(record.status)} label={record.status} /></td>
                  <td>{formatDateTime(record.created_at)}</td>
                  <td>{record.approval_user_ids.length || "-"}</td>
                  <td>{targetLabel(record.target)}</td>
                </tr>
              )}
              {!history.length && <tr><td colSpan={6} className="muted">i18n:govoplan-admin.no_applied_configuration_changes.6a3ae4a7</td></tr>}
            </tbody>
          </table>
        </div>
      </Card>
    </AdminPageLayout>);

}

function statusTone(status: string): string {
  if (status === "approved" || status === "applied") return "success";
  if (status === "pending_approval") return "warning";
  if (status === "rejected") return "error";
  return "inactive";
}

function targetLabel(target?: Record<string, unknown>): string {
  if (!target || !Object.keys(target).length) return "-";
  return Object.entries(target).map(([key, value]) => `${key}: ${String(value)}`).join(", ");
}

function sortConfigurationRequests(left: ConfigurationChangeRequest, right: ConfigurationChangeRequest): number {
  return new Date(right.updated_at || right.requested_at).getTime() - new Date(left.updated_at || left.requested_at).getTime();
}

function sortConfigurationHistory(left: ConfigurationChangeRecord, right: ConfigurationChangeRecord): number {
  return right.version - left.version;
}
