"use client";

import { useEffect, useState } from "react";
import type { CommercialTerms, PaymentMilestone, PricingModel } from "@capakraken/shared";
import {
  computeCommercialTermsSummary,
  computeMilestoneAmounts,
  validatePaymentMilestones,
} from "@capakraken/engine";
import { clsx } from "clsx";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
import { formatMoney } from "~/lib/format.js";
import { trpc } from "~/lib/trpc/client.js";

interface Props {
  estimateId: string;
  baseCostCents: number;
  basePriceCents: number;
  baseCurrency: string;
  canEdit: boolean;
}

const PRICING_MODELS: Array<{ value: PricingModel; label: string }> = [
  { value: "fixed_price", label: "Fixed Price" },
  { value: "time_and_materials", label: "Time & Materials" },
  { value: "hybrid", label: "Hybrid" },
];

export function CommercialTermsEditor({
  estimateId,
  baseCostCents,
  basePriceCents,
  baseCurrency,
  canEdit,
}: Props) {
  const utils = trpc.useUtils();
  const { data, isLoading } = trpc.estimate.getCommercialTerms.useQuery({
    estimateId,
  });

  const updateMutation = trpc.estimate.updateCommercialTerms.useMutation({
    onSuccess: async () => {
      await utils.estimate.getCommercialTerms.invalidate({ estimateId });
    },
  });

  const [terms, setTerms] = useState<CommercialTerms>({
    pricingModel: "fixed_price",
    contingencyPercent: 0,
    discountPercent: 0,
    paymentTermDays: 30,
    paymentMilestones: [],
    warrantyMonths: 0,
  });
  const [dirty, setDirty] = useState(false);

  useEffect(() => {
    if (data?.terms) {
      setTerms(data.terms);
      setDirty(false);
    }
  }, [data]);

  function update(patch: Partial<CommercialTerms>) {
    setTerms((prev) => ({ ...prev, ...patch }));
    setDirty(true);
  }

  function save() {
    updateMutation.mutate({
      estimateId,
      terms,
    });
    setDirty(false);
  }

  const summary = computeCommercialTermsSummary({
    baseCostCents,
    basePriceCents,
    terms,
  });

  const milestoneWarnings = validatePaymentMilestones(terms.paymentMilestones);
  const milestoneAmounts = computeMilestoneAmounts(
    summary.adjustedPriceCents,
    terms.paymentMilestones,
  );

  if (isLoading) {
    return (
      <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
        <div className="h-6 w-48 shimmer-skeleton rounded" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Adjusted financials summary */}
      <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
          <p className="text-xs uppercase tracking-wide text-gray-400">
            Adjusted Cost <InfoTooltip content="Base cost + contingency. Adjusted cost = base cost x (1 + contingency %)." />
          </p>
          <p className="mt-2 text-2xl font-semibold text-gray-900">
            {formatMoney(summary.adjustedCostCents, baseCurrency)}
          </p>
          {summary.contingencyCents > 0 && (
            <p className="mt-1 text-xs text-amber-600">
              +{formatMoney(summary.contingencyCents, baseCurrency)} contingency
            </p>
          )}
        </div>
        <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
          <p className="text-xs uppercase tracking-wide text-gray-400">
            Adjusted Price <InfoTooltip content="Base price minus discount. Adjusted price = base price x (1 - discount %)." />
          </p>
          <p className="mt-2 text-2xl font-semibold text-gray-900">
            {formatMoney(summary.adjustedPriceCents, baseCurrency)}
          </p>
          {summary.discountCents > 0 && (
            <p className="mt-1 text-xs text-red-600">
              -{formatMoney(summary.discountCents, baseCurrency)} discount
            </p>
          )}
        </div>
        <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
          <p className="text-xs uppercase tracking-wide text-gray-400">
            Adjusted Margin <InfoTooltip content="Adjusted margin = adjusted price - adjusted cost. Margin % = margin / adjusted price x 100." />
          </p>
          <p
            className={clsx(
              "mt-2 text-2xl font-semibold",
              summary.adjustedMarginCents >= 0
                ? "text-emerald-700"
                : "text-red-700",
            )}
          >
            {formatMoney(summary.adjustedMarginCents, baseCurrency)}
          </p>
          <p className="mt-1 text-xs text-gray-500">
            {summary.adjustedMarginPercent.toFixed(1)}% of price
          </p>
        </div>
        <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
          <p className="text-xs uppercase tracking-wide text-gray-400">
            Pricing Model <InfoTooltip content="Fixed Price: agreed total. Time & Materials: billed per actual hour. Hybrid: mix of both." />
          </p>
          <p className="mt-2 text-lg font-semibold text-gray-900">
            {PRICING_MODELS.find((m) => m.value === terms.pricingModel)?.label ??
              terms.pricingModel}
          </p>
          {terms.warrantyMonths > 0 && (
            <p className="mt-1 text-xs text-gray-500">
              {terms.warrantyMonths} mo warranty
            </p>
          )}
        </div>
      </div>

      {/* Terms editor */}
      <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-base font-semibold text-gray-900">
            Commercial Terms
          </h3>
          {canEdit && dirty && (
            <button
              type="button"
              onClick={save}
              disabled={updateMutation.isPending}
              className="rounded-lg bg-brand-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-brand-700 disabled:opacity-50"
            >
              {updateMutation.isPending ? "Saving..." : "Save"}
            </button>
          )}
        </div>

        <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
          {/* Pricing Model */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">
              Pricing Model <InfoTooltip content="How the project will be billed to the client." />
            </label>
            <select
              value={terms.pricingModel}
              onChange={(e) =>
                update({ pricingModel: e.target.value as PricingModel })
              }
              disabled={!canEdit}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm disabled:bg-gray-50"
            >
              {PRICING_MODELS.map((m) => (
                <option key={m.value} value={m.value}>
                  {m.label}
                </option>
              ))}
            </select>
          </div>

          {/* Contingency % */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">
              Contingency % <InfoTooltip content="Risk buffer added to the base cost. Adjusted cost = base cost x (1 + contingency %)." />
            </label>
            <input
              type="number"
              min={0}
              max={100}
              step={0.5}
              value={terms.contingencyPercent}
              onChange={(e) =>
                update({ contingencyPercent: parseFloat(e.target.value) || 0 })
              }
              disabled={!canEdit}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm tabular-nums disabled:bg-gray-50"
            />
          </div>

          {/* Discount % */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">
              Discount % <InfoTooltip content="Client discount applied to the base price. Adjusted price = base price x (1 - discount %)." />
            </label>
            <input
              type="number"
              min={0}
              max={100}
              step={0.5}
              value={terms.discountPercent}
              onChange={(e) =>
                update({ discountPercent: parseFloat(e.target.value) || 0 })
              }
              disabled={!canEdit}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm tabular-nums disabled:bg-gray-50"
            />
          </div>

          {/* Payment Terms */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">
              Payment Terms (days) <InfoTooltip content="Number of days after invoice date within which payment is due." />
            </label>
            <input
              type="number"
              min={0}
              max={365}
              value={terms.paymentTermDays}
              onChange={(e) =>
                update({ paymentTermDays: parseInt(e.target.value) || 0 })
              }
              disabled={!canEdit}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm tabular-nums disabled:bg-gray-50"
            />
          </div>

          {/* Warranty */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">
              Warranty (months) <InfoTooltip content="Post-delivery warranty period during which defects are covered at no extra cost." />
            </label>
            <input
              type="number"
              min={0}
              max={60}
              value={terms.warrantyMonths}
              onChange={(e) =>
                update({ warrantyMonths: parseInt(e.target.value) || 0 })
              }
              disabled={!canEdit}
              className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm tabular-nums disabled:bg-gray-50"
            />
          </div>
        </div>

        {/* Notes */}
        <div className="mt-4">
          <label className="block text-xs font-medium text-gray-500 mb-1">
            Notes <InfoTooltip content="Free-text notes about the commercial terms, e.g. special conditions or negotiation context." />
          </label>
          <textarea
            value={terms.notes ?? ""}
            onChange={(e) =>
              update({ notes: e.target.value || null })
            }
            disabled={!canEdit}
            rows={2}
            className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm disabled:bg-gray-50"
            placeholder="Additional commercial notes..."
          />
        </div>
      </div>

      {/* Payment Milestones */}
      <div className="rounded-3xl border border-gray-200 bg-white p-5 shadow-sm">
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-base font-semibold text-gray-900">
            Payment Milestones <InfoTooltip content="Define when payments are due as a percentage of the adjusted price. Milestones should sum to 100%." />
          </h3>
          {canEdit && (
            <button
              type="button"
              onClick={() =>
                update({
                  paymentMilestones: [
                    ...terms.paymentMilestones,
                    { label: "", percent: 0 },
                  ],
                })
              }
              className="rounded-lg border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50"
            >
              + Add milestone
            </button>
          )}
        </div>

        {milestoneWarnings.length > 0 && (
          <div className="mb-3 rounded-lg border border-amber-200 bg-amber-50 p-3">
            <ul className="space-y-1">
              {milestoneWarnings.map((w, i) => (
                <li key={i} className="text-xs text-amber-700">
                  {w}
                </li>
              ))}
            </ul>
          </div>
        )}

        {terms.paymentMilestones.length === 0 ? (
          <p className="text-sm text-gray-400">
            No payment milestones defined.
          </p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-left text-sm">
              <thead>
                <tr className="border-b border-gray-200 text-xs uppercase tracking-wider text-gray-500">
                  <th className="py-2 pr-3 font-medium">Milestone</th>
                  <th className="px-3 py-2 text-right font-medium w-24">%</th>
                  <th className="px-3 py-2 text-right font-medium">Amount</th>
                  <th className="px-3 py-2 font-medium w-36">Due Date</th>
                  {canEdit && (
                    <th className="pl-3 py-2 font-medium w-12" />
                  )}
                </tr>
              </thead>
              <tbody>
                {terms.paymentMilestones.map((ms, idx) => {
                  const amount = milestoneAmounts[idx];
                  return (
                    <tr key={idx} className="border-b border-gray-100">
                      <td className="py-2 pr-3">
                        {canEdit ? (
                          <input
                            type="text"
                            value={ms.label}
                            onChange={(e) => {
                              const updated = [...terms.paymentMilestones];
                              updated[idx] = { ...ms, label: e.target.value };
                              update({ paymentMilestones: updated });
                            }}
                            className="w-full rounded border border-gray-200 px-2 py-1 text-sm"
                            placeholder="e.g. Kickoff"
                          />
                        ) : (
                          <span className="text-gray-900">{ms.label}</span>
                        )}
                      </td>
                      <td className="px-3 py-2 text-right">
                        {canEdit ? (
                          <input
                            type="number"
                            min={0}
                            max={100}
                            step={1}
                            value={ms.percent}
                            onChange={(e) => {
                              const updated = [...terms.paymentMilestones];
                              updated[idx] = {
                                ...ms,
                                percent: parseFloat(e.target.value) || 0,
                              };
                              update({ paymentMilestones: updated });
                            }}
                            className="w-20 rounded border border-gray-200 px-2 py-1 text-right text-sm tabular-nums"
                          />
                        ) : (
                          <span className="tabular-nums text-gray-700">
                            {ms.percent}%
                          </span>
                        )}
                      </td>
                      <td className="px-3 py-2 text-right tabular-nums text-gray-700">
                        {amount
                          ? formatMoney(amount.amountCents, baseCurrency)
                          : "—"}
                      </td>
                      <td className="px-3 py-2">
                        {canEdit ? (
                          <input
                            type="date"
                            value={ms.dueDate ?? ""}
                            onChange={(e) => {
                              const updated = [...terms.paymentMilestones];
                              updated[idx] = {
                                ...ms,
                                dueDate: e.target.value || null,
                              };
                              update({ paymentMilestones: updated });
                            }}
                            className="rounded border border-gray-200 px-2 py-1 text-sm"
                          />
                        ) : (
                          <span className="text-gray-700">
                            {ms.dueDate ?? "—"}
                          </span>
                        )}
                      </td>
                      {canEdit && (
                        <td className="pl-3 py-2 text-center">
                          <button
                            type="button"
                            onClick={() => {
                              const updated = terms.paymentMilestones.filter(
                                (_, i) => i !== idx,
                              );
                              update({ paymentMilestones: updated });
                            }}
                            className="text-red-400 hover:text-red-600 text-xs"
                            title="Remove"
                          >
                            X
                          </button>
                        </td>
                      )}
                    </tr>
                  );
                })}
                {/* Total row */}
                <tr className="border-t-2 border-gray-300 font-semibold">
                  <td className="py-2 pr-3 text-gray-900">Total</td>
                  <td className="px-3 py-2 text-right tabular-nums text-gray-900">
                    {terms.paymentMilestones
                      .reduce((sum, m) => sum + m.percent, 0)
                      .toFixed(1)}
                    %
                  </td>
                  <td className="px-3 py-2 text-right tabular-nums text-gray-900">
                    {formatMoney(
                      milestoneAmounts.reduce((s, a) => s + a.amountCents, 0),
                      baseCurrency,
                    )}
                  </td>
                  <td />
                  {canEdit && <td />}
                </tr>
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}
