"use client";

import { useState } from "react";
import { AnimatedModal } from "~/components/ui/AnimatedModal.js";
import { ConfirmDialog } from "~/components/ui/ConfirmDialog.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
import { trpc } from "~/lib/trpc/client.js";

const TRIGGER_TYPES = ["SICK", "VACATION", "PUBLIC_HOLIDAY", "CUSTOM"] as const;
const COST_EFFECTS = ["CHARGE", "ZERO", "REDUCE"] as const;
const CHARGEABILITY_EFFECTS = ["COUNT", "SKIP"] as const;
const ORDER_TYPES = ["BD", "CHARGEABLE", "INTERNAL", "OVERHEAD"] as const;

const TRIGGER_LABELS: Record<string, string> = {
  SICK: "Sick Leave",
  VACATION: "Vacation",
  PUBLIC_HOLIDAY: "Public Holiday",
  CUSTOM: "Custom",
};

const COST_LABELS: Record<string, string> = {
  CHARGE: "Charge to Project",
  ZERO: "No Project Cost",
  REDUCE: "Reduced Cost",
};

const CHG_LABELS: Record<string, string> = {
  COUNT: "Person Chargeable",
  SKIP: "Not Chargeable",
};

type RuleRow = {
  id: string;
  name: string;
  description: string | null;
  triggerType: string;
  projectId: string | null;
  orderType: string | null;
  costEffect: string;
  costReductionPercent: number | null;
  chargeabilityEffect: string;
  priority: number;
  isActive: boolean;
  project?: { id: string; name: string; shortCode: string } | null;
};

type EditingRule = {
  id?: string;
  name: string;
  description: string;
  triggerType: string;
  projectId: string;
  orderType: string;
  costEffect: string;
  costReductionPercent: number;
  chargeabilityEffect: string;
  priority: number;
  isActive: boolean;
};

const emptyRule: EditingRule = {
  name: "",
  description: "",
  triggerType: "SICK",
  projectId: "",
  orderType: "",
  costEffect: "ZERO",
  costReductionPercent: 0,
  chargeabilityEffect: "COUNT",
  priority: 0,
  isActive: true,
};

export function CalculationRulesClient() {
  const [editing, setEditing] = useState<EditingRule | null>(null);
  const [confirmDeleteRule, setConfirmDeleteRule] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const utils = trpc.useUtils();
  const { data: rules, isLoading } = trpc.calculationRule.list.useQuery();

  const createMut = trpc.calculationRule.create.useMutation({
    onSuccess: () => { void utils.calculationRule.list.invalidate(); setEditing(null); },
    onError: (e) => setError(e.message),
  });
  const updateMut = trpc.calculationRule.update.useMutation({
    onSuccess: () => { void utils.calculationRule.list.invalidate(); setEditing(null); },
    onError: (e) => setError(e.message),
  });
  const deleteMut = trpc.calculationRule.delete.useMutation({
    onSuccess: () => { void utils.calculationRule.list.invalidate(); },
    onError: (e) => setError(e.message),
  });

  function openCreate() {
    setEditing({ ...emptyRule });
    setError(null);
  }

  function openEdit(r: RuleRow) {
    setEditing({
      id: r.id,
      name: r.name,
      description: r.description ?? "",
      triggerType: r.triggerType,
      projectId: r.projectId ?? "",
      orderType: r.orderType ?? "",
      costEffect: r.costEffect,
      costReductionPercent: r.costReductionPercent ?? 0,
      chargeabilityEffect: r.chargeabilityEffect,
      priority: r.priority,
      isActive: r.isActive,
    });
    setError(null);
  }

  function handleSave() {
    if (!editing) return;
    setError(null);

    const payload = {
      name: editing.name,
      triggerType: editing.triggerType as (typeof TRIGGER_TYPES)[number],
      costEffect: editing.costEffect as (typeof COST_EFFECTS)[number],
      chargeabilityEffect: editing.chargeabilityEffect as (typeof CHARGEABILITY_EFFECTS)[number],
      priority: editing.priority,
      isActive: editing.isActive,
      ...(editing.description ? { description: editing.description } : {}),
      ...(editing.projectId ? { projectId: editing.projectId } : {}),
      ...(editing.orderType ? { orderType: editing.orderType } : {}),
      ...(editing.costEffect === "REDUCE" ? { costReductionPercent: editing.costReductionPercent } : {}),
    };

    if (editing.id) {
      updateMut.mutate({ id: editing.id, ...payload });
    } else {
      createMut.mutate(payload);
    }
  }

  if (isLoading) return <div className="p-6 text-sm text-gray-500">Loading...</div>;

  return (
    <div className="mx-auto max-w-5xl p-6">
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">Calculation Rules</h1>
          <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
            Configure how absences affect project costs and chargeability reporting.
          </p>
        </div>
        <button
          onClick={openCreate}
          className="rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700"
        >
          Add Rule
        </button>
      </div>

      {error && (
        <div className="mb-4 rounded-md bg-red-50 p-3 text-sm text-red-700 dark:bg-red-900/20 dark:text-red-400">
          {error}
        </div>
      )}

      {/* ── Rules Table ── */}
      <div className="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-700">
        <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
          <thead className="bg-gray-50 dark:bg-gray-800">
            <tr>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Name <InfoTooltip content="A descriptive label for this rule. Use clear names so admins can quickly identify what each rule does." /></span>
              </th>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Trigger <InfoTooltip content="The absence type that activates this rule: Sick Leave, Vacation, Public Holiday, or Custom. Determines when the cost/chargeability logic applies." /></span>
              </th>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Cost Effect <InfoTooltip content="How this absence affects project costs. 'Charge to Project' bills the project, 'No Project Cost' absorbs the cost centrally, 'Reduced Cost' applies a percentage discount." /></span>
              </th>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Chargeability <InfoTooltip content="Whether the person's time counts as chargeable during this absence. 'Person Chargeable' includes the time in chargeability metrics; 'Not Chargeable' excludes it." /></span>
              </th>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Scope <InfoTooltip content="Limits the rule to a specific project or order type (BD, Chargeable, Internal, Overhead). 'Global' means the rule applies to all projects." /></span>
              </th>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Priority <InfoTooltip content="When multiple rules match the same absence, the one with the highest priority number wins. Use this to create specific overrides for certain projects." /></span>
              </th>
              <th className="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500">
                <span className="flex items-center">Active <InfoTooltip content="Only active rules are evaluated. Deactivate a rule to temporarily disable it without deleting." /></span>
              </th>
              <th className="px-4 py-3 text-right text-xs font-medium uppercase text-gray-500">Actions</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200 bg-white dark:divide-gray-700 dark:bg-gray-900">
            {(rules ?? []).map((r) => {
              const rule = r as unknown as RuleRow;
              return (
                <tr key={rule.id} className={rule.isActive ? "" : "opacity-50"}>
                  <td className="px-4 py-3 text-sm font-medium text-gray-900 dark:text-gray-100">{rule.name}</td>
                  <td className="px-4 py-3 text-sm text-gray-600 dark:text-gray-300">
                    <span className="rounded bg-gray-100 px-2 py-0.5 text-xs dark:bg-gray-700">
                      {TRIGGER_LABELS[rule.triggerType] ?? rule.triggerType}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-sm text-gray-600 dark:text-gray-300">
                    {COST_LABELS[rule.costEffect] ?? rule.costEffect}
                    {rule.costEffect === "REDUCE" && rule.costReductionPercent != null && (
                      <span className="ml-1 text-xs text-gray-400">({rule.costReductionPercent}%)</span>
                    )}
                  </td>
                  <td className="px-4 py-3 text-sm text-gray-600 dark:text-gray-300">
                    {CHG_LABELS[rule.chargeabilityEffect] ?? rule.chargeabilityEffect}
                  </td>
                  <td className="px-4 py-3 text-sm text-gray-500 dark:text-gray-400">
                    {rule.project ? rule.project.shortCode : rule.orderType ? rule.orderType : "Global"}
                  </td>
                  <td className="px-4 py-3 text-sm text-gray-500">{rule.priority}</td>
                  <td className="px-4 py-3 text-sm">
                    <span className={`inline-block h-2 w-2 rounded-full ${rule.isActive ? "bg-green-500" : "bg-gray-300"}`} />
                  </td>
                  <td className="px-4 py-3 text-right text-sm">
                    <button onClick={() => openEdit(rule)} className="mr-2 text-blue-600 hover:underline dark:text-blue-400">Edit</button>
                    <button
                      onClick={() => setConfirmDeleteRule(rule.id)}
                      className="text-red-600 hover:underline dark:text-red-400"
                    >
                      Delete
                    </button>
                  </td>
                </tr>
              );
            })}
            {(rules ?? []).length === 0 && (
              <tr>
                <td colSpan={8} className="px-4 py-8 text-center text-sm text-gray-500">
                  No calculation rules configured. Add a rule to control how absences affect costs and chargeability.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {/* ── Edit/Create Modal ── */}
      <AnimatedModal open={editing !== null} onClose={() => setEditing(null)} maxWidth="max-w-lg">
        {editing && (<>
            <div className="p-6">
            <h2 className="mb-4 text-lg font-semibold text-gray-900 dark:text-gray-100">
              {editing.id ? "Edit Rule" : "New Rule"}
            </h2>
            <div className="space-y-4">
              <div>
                <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Name <InfoTooltip content="A unique, descriptive name for this calculation rule." /></label>
                <input
                  value={editing.name}
                  onChange={(e) => setEditing({ ...editing, name: e.target.value })}
                  className="w-full rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                />
              </div>
              <div>
                <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Description <InfoTooltip content="Optional notes explaining when and why this rule exists." /></label>
                <textarea
                  value={editing.description}
                  onChange={(e) => setEditing({ ...editing, description: e.target.value })}
                  rows={2}
                  className="w-full rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                />
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Trigger Type <InfoTooltip content="The type of absence event that activates this rule." /></label>
                  <select
                    value={editing.triggerType}
                    onChange={(e) => setEditing({ ...editing, triggerType: e.target.value })}
                    className="w-full rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                  >
                    {TRIGGER_TYPES.map((t) => <option key={t} value={t}>{TRIGGER_LABELS[t]}</option>)}
                  </select>
                </div>
                <div>
                  <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Order Type (optional) <InfoTooltip content="Restricts this rule to a specific order type. Leave as 'All' to apply globally." /></label>
                  <select
                    value={editing.orderType}
                    onChange={(e) => setEditing({ ...editing, orderType: e.target.value })}
                    className="w-full rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                  >
                    <option value="">All (Global)</option>
                    {ORDER_TYPES.map((t) => <option key={t} value={t}>{t}</option>)}
                  </select>
                </div>
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Cost Effect <InfoTooltip content="Determines how costs are attributed during this absence. 'Charge' bills the project, 'Zero' removes cost, 'Reduce' applies a percentage reduction." /></label>
                  <select
                    value={editing.costEffect}
                    onChange={(e) => setEditing({ ...editing, costEffect: e.target.value })}
                    className="w-full rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                  >
                    {COST_EFFECTS.map((t) => <option key={t} value={t}>{COST_LABELS[t]}</option>)}
                  </select>
                </div>
                <div>
                  <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Chargeability <InfoTooltip content="Controls whether this absence counts toward the person's chargeability KPI." /></label>
                  <select
                    value={editing.chargeabilityEffect}
                    onChange={(e) => setEditing({ ...editing, chargeabilityEffect: e.target.value })}
                    className="w-full rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                  >
                    {CHARGEABILITY_EFFECTS.map((t) => <option key={t} value={t}>{CHG_LABELS[t]}</option>)}
                  </select>
                </div>
              </div>
              {editing.costEffect === "REDUCE" && (
                <div>
                  <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">
                    Reduction Percent (0-100) <InfoTooltip content="The percentage by which the cost is reduced. E.g. 50 means the project is charged half the normal rate." />
                  </label>
                  <input
                    type="number"
                    min={0}
                    max={100}
                    value={editing.costReductionPercent}
                    onChange={(e) => setEditing({ ...editing, costReductionPercent: Number(e.target.value) })}
                    className="w-32 rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                  />
                </div>
              )}
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="mb-1 flex items-center text-sm font-medium text-gray-700 dark:text-gray-300">Priority <InfoTooltip content="Higher numbers take precedence when multiple rules match. Use 0 for default rules and higher values for specific overrides." /></label>
                  <input
                    type="number"
                    min={0}
                    value={editing.priority}
                    onChange={(e) => setEditing({ ...editing, priority: Number(e.target.value) })}
                    className="w-32 rounded-md border px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                  />
                </div>
                <div className="flex items-end">
                  <label className="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
                    <input
                      type="checkbox"
                      checked={editing.isActive}
                      onChange={(e) => setEditing({ ...editing, isActive: e.target.checked })}
                      className="rounded border-gray-300"
                    />
                    Active <InfoTooltip content="Inactive rules are ignored during cost calculations." />
                  </label>
                </div>
              </div>
            </div>
            <div className="mt-6 flex justify-end gap-3">
              <button
                onClick={() => setEditing(null)}
                className="rounded-md border px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700"
              >
                Cancel
              </button>
              <button
                onClick={handleSave}
                disabled={!editing.name || createMut.isPending || updateMut.isPending}
                className="rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50"
              >
                {createMut.isPending || updateMut.isPending ? "Saving..." : "Save"}
              </button>
            </div>
            </div>
        </>)}
      </AnimatedModal>

      {confirmDeleteRule && (
        <ConfirmDialog
          title="Delete rule"
          message="Are you sure you want to delete this calculation rule?"
          confirmLabel="Delete"
          variant="danger"
          onConfirm={() => {
            deleteMut.mutate({ id: confirmDeleteRule });
            setConfirmDeleteRule(null);
          }}
          onCancel={() => setConfirmDeleteRule(null)}
        />
      )}
    </div>
  );
}
