"use client";

import { useState, useMemo, useEffect } from "react";
import { InfoRow, formatDate } from "../primitives";

function toDateInputValue(d: Date | string | null | undefined): string {
  if (!d) return "";
  try {
    const date = typeof d === "string" ? new Date(d) : d;
    if (Number.isNaN(date.getTime())) return "";
    const yyyy = date.getUTCFullYear();
    const mm = String(date.getUTCMonth() + 1).padStart(2, "0");
    const dd = String(date.getUTCDate()).padStart(2, "0");
    return `${yyyy}-${mm}-${dd}`;
  } catch {
    return "";
  }
}

function dateInputToIso(value: string): string | null {
  if (!value) return null;
  return new Date(`${value}T00:00:00.000Z`).toISOString();
}

interface PibiDatesEditorProps {
  dealId: string;
  portfolioId: string;
  initialOrderDate: Date | string | null;
  initialCompletedDate: Date | string | null;
  canEdit: boolean;
}

export function PibiDatesEditor({
  dealId,
  portfolioId,
  initialOrderDate,
  initialCompletedDate,
  canEdit,
}: PibiDatesEditorProps) {
  const initialOrder = useMemo(
    () => toDateInputValue(initialOrderDate),
    [initialOrderDate],
  );
  const initialCompleted = useMemo(
    () => toDateInputValue(initialCompletedDate),
    [initialCompletedDate],
  );

  const [orderValue, setOrderValue] = useState(initialOrder);
  const [completedValue, setCompletedValue] = useState(initialCompleted);
  const [savedOrder, setSavedOrder] = useState(initialOrder);
  const [savedCompleted, setSavedCompleted] = useState(initialCompleted);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setOrderValue(initialOrder);
    setSavedOrder(initialOrder);
  }, [initialOrder]);
  useEffect(() => {
    setCompletedValue(initialCompleted);
    setSavedCompleted(initialCompleted);
  }, [initialCompleted]);

  const dirty =
    orderValue !== savedOrder || completedValue !== savedCompleted;

  async function handleSave() {
    if (!dirty) return;
    setSubmitting(true);
    setError(null);
    const fields: Record<string, string | null> = {};
    if (orderValue !== savedOrder) {
      fields.pibi_order_date = dateInputToIso(orderValue);
    }
    if (completedValue !== savedCompleted) {
      fields.pibi_completed_date = dateInputToIso(completedValue);
    }
    const prevOrder = savedOrder;
    const prevCompleted = savedCompleted;
    setSavedOrder(orderValue);
    setSavedCompleted(completedValue);

    try {
      const res = await fetch(
        `/api/portfolio/${portfolioId}/deal-properties`,
        {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ dealId, fields }),
        },
      );
      if (!res.ok) {
        setSavedOrder(prevOrder);
        setSavedCompleted(prevCompleted);
        setOrderValue(prevOrder);
        setCompletedValue(prevCompleted);
        const json = await res.json().catch(() => ({}));
        setError(
          typeof json.error === "string"
            ? json.error
            : "Failed to update PIBI dates",
        );
        return;
      }
      const json = (await res.json()) as {
        results: Record<string, { ok: boolean; error?: string }>;
        hubspotSync: "ok" | "failed" | "skipped";
        hubspotError?: string;
      };
      const fieldErrors = Object.entries(json.results ?? {})
        .filter(([, r]) => !r.ok)
        .map(([k, r]) => `${k}: ${r.error ?? "rejected"}`);
      if (fieldErrors.length > 0) {
        setError(fieldErrors.join("; "));
      } else if (json.hubspotSync === "failed") {
        setError(
          json.hubspotError
            ? `Saved locally — HubSpot sync failed: ${json.hubspotError}`
            : "Saved locally — HubSpot sync failed",
        );
      }
    } catch (err) {
      setSavedOrder(prevOrder);
      setSavedCompleted(prevCompleted);
      setOrderValue(prevOrder);
      setCompletedValue(prevCompleted);
      setError(err instanceof Error ? err.message : "Failed to update PIBI dates");
    } finally {
      setSubmitting(false);
    }
  }

  if (!canEdit) {
    return (
      <div className="divide-y divide-gray-50">
        <InfoRow label="PIBI Order Date" value={formatDate(initialOrderDate)} />
        <InfoRow
          label="PIBI Completed Date"
          value={formatDate(initialCompletedDate)}
        />
      </div>
    );
  }

  return (
    <div className="space-y-3">
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
        <label className="flex flex-col gap-1">
          <span className="text-xs text-gray-500 font-medium">
            PIBI Order Date
          </span>
          <input
            type="date"
            data-testid="pibi-order-date-input"
            value={orderValue}
            onChange={(e) => setOrderValue(e.target.value)}
            disabled={submitting}
            className="rounded-lg border border-gray-200 px-3 py-1.5 text-xs text-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-300"
          />
        </label>
        <label className="flex flex-col gap-1">
          <span className="text-xs text-gray-500 font-medium">
            PIBI Completed Date
          </span>
          <input
            type="date"
            data-testid="pibi-completed-date-input"
            value={completedValue}
            onChange={(e) => setCompletedValue(e.target.value)}
            disabled={submitting}
            className="rounded-lg border border-gray-200 px-3 py-1.5 text-xs text-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-200 focus:border-blue-300"
          />
        </label>
      </div>
      <div className="flex items-center justify-between gap-3">
        <p className="text-[11px] text-gray-400">
          Pick the actual date — leave blank to clear. Changes sync to HubSpot.
        </p>
        <button
          type="button"
          data-testid="pibi-save-button"
          onClick={handleSave}
          disabled={!dirty || submitting}
          className="text-xs font-medium px-3 py-1.5 rounded-lg bg-brandblue text-white hover:bg-brandmidblue disabled:opacity-50 transition-colors"
        >
          {submitting ? "Saving…" : "Save PIBI Dates"}
        </button>
      </div>
      {error && (
        <p
          data-testid="pibi-error"
          className="text-xs text-red-600 bg-red-50 px-3 py-2 rounded-lg"
        >
          {error}
        </p>
      )}
    </div>
  );
}
