"use client";

import { useState } from "react";
import { useRules, useCreateRule, useUpdateRule, useDeleteRule, useApplyRules, useTags } from "@/lib/hooks";
import { CATEGORIES, formatCategory } from "@/lib/categories";

const FIELDS = [
  { value: "merchant_normalized", label: "Merchant" },
  { value: "description", label: "Description" },
  { value: "category", label: "Category" },
  { value: "bank_name", label: "Bank" },
  { value: "amount", label: "Amount" },
] as const;

const TEXT_OPS = [
  { value: "contains", label: "contains" },
  { value: "equals", label: "equals" },
  { value: "starts_with", label: "starts with" },
  { value: "not_equals", label: "not equals" },
];
const AMOUNT_OPS = [
  { value: "equals", label: "=" },
  { value: "not_equals", label: "≠" },
  { value: "gt", label: ">" },
  { value: "lt", label: "<" },
];

type Condition = { field: string; operator: string; value: string };
type Actions = { set_category?: string; add_tag_ids?: number[]; set_merchant?: string };

function humanCondition(c: Condition): string {
  const fieldLabel = FIELDS.find((f) => f.value === c.field)?.label || c.field;
  const ops = [...TEXT_OPS, ...AMOUNT_OPS];
  const opText = ops.find((o) => o.value === c.operator)?.label || c.operator;
  return `${fieldLabel} ${opText} "${c.value}"`;
}

function humanAction(a: Actions, tagNames: Map<number, string>): string {
  const parts: string[] = [];
  if (a.set_category) parts.push(`set category: ${formatCategory(a.set_category)}`);
  if (a.set_merchant) parts.push(`set merchant: ${a.set_merchant}`);
  if (a.add_tag_ids?.length) {
    const names = a.add_tag_ids.map((id) => tagNames.get(id) || `tag#${id}`).join(", ");
    parts.push(`add tags: ${names}`);
  }
  return parts.length ? "→ " + parts.join(", ") : "(no actions)";
}

export default function RulesPage() {
  const { data: rules = [], isLoading } = useRules();
  const { data: tags = [] } = useTags();
  const createRule = useCreateRule();
  const updateRule = useUpdateRule();
  const deleteRule = useDeleteRule();
  const applyRules = useApplyRules();

  const tagNames = new Map(tags.map((t) => [t.id, t.name]));

  const [showForm, setShowForm] = useState(false);
  const [applyResult, setApplyResult] = useState<{ matched: number; transactions_affected: number } | null>(null);
  const [name, setName] = useState("");
  const [conditions, setConditions] = useState<Condition[]>([]);
  const [actions, setActions] = useState<Actions>({});
  const [priority, setPriority] = useState(0);

  function addCondition() {
    setConditions([...conditions, { field: "merchant_normalized", operator: "contains", value: "" }]);
  }

  function updateCondition(i: number, patch: Partial<Condition>) {
    setConditions(conditions.map((c, idx) => (idx === i ? { ...c, ...patch } : c)));
  }

  function removeCondition(i: number) {
    setConditions(conditions.filter((_, idx) => idx !== i));
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    await createRule.mutateAsync({ name, conditions, actions, enabled: true, priority });
    setName("");
    setConditions([]);
    setActions({});
    setPriority(0);
    setShowForm(false);
  }

  async function handleApply() {
    const result = await applyRules.mutateAsync();
    setApplyResult(result);
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h2 className="text-xl font-semibold">Rules</h2>
        <div className="flex gap-2">
          <button
            onClick={handleApply}
            disabled={applyRules.isPending}
            className="px-4 py-2 bg-emerald-600 hover:bg-emerald-500 text-white rounded-lg text-sm font-medium disabled:opacity-50"
          >
            {applyRules.isPending ? "Applying..." : "Apply All Rules"}
          </button>
          <button
            onClick={() => setShowForm(!showForm)}
            className="px-4 py-2 bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg text-sm font-medium"
          >
            {showForm ? "Cancel" : "New Rule"}
          </button>
        </div>
      </div>

      {applyResult && (
        <div className="p-4 bg-emerald-900/30 border border-emerald-700 rounded-lg text-sm">
          Applied: <strong>{applyResult.matched}</strong> condition matches across{" "}
          <strong>{applyResult.transactions_affected}</strong> transactions.
          <button onClick={() => setApplyResult(null)} className="ml-4 text-zinc-400 hover:text-white">
            dismiss
          </button>
        </div>
      )}

      {showForm && (
        <form onSubmit={handleSubmit} className="bg-zinc-900 border border-zinc-700 rounded-xl p-6 space-y-4">
          <h3 className="font-semibold text-sm text-zinc-300">New Rule</h3>

          <div>
            <label className="block text-xs text-zinc-500 mb-1">Rule Name</label>
            <input
              value={name}
              onChange={(e) => setName(e.target.value)}
              required
              placeholder="e.g. Tag Woolworths as groceries"
              className="w-full bg-zinc-800 border border-zinc-700 rounded-lg px-3 py-2 text-sm"
            />
          </div>

          <div>
            <div className="flex items-center justify-between mb-2">
              <label className="text-xs text-zinc-500">Conditions (ALL must match)</label>
              <button type="button" onClick={addCondition} className="text-xs text-indigo-400 hover:text-indigo-300">
                + Add condition
              </button>
            </div>
            {conditions.map((cond, i) => {
              const isAmount = cond.field === "amount";
              const ops = isAmount ? AMOUNT_OPS : TEXT_OPS;
              return (
                <div key={i} className="flex gap-2 mb-2 items-center">
                  <select
                    value={cond.field}
                    onChange={(e) =>
                      updateCondition(i, {
                        field: e.target.value,
                        operator: e.target.value === "amount" ? "equals" : "contains",
                      })
                    }
                    className="bg-zinc-800 border border-zinc-700 rounded px-2 py-1.5 text-sm"
                  >
                    {FIELDS.map((f) => (
                      <option key={f.value} value={f.value}>
                        {f.label}
                      </option>
                    ))}
                  </select>
                  <select
                    value={cond.operator}
                    onChange={(e) => updateCondition(i, { operator: e.target.value })}
                    className="bg-zinc-800 border border-zinc-700 rounded px-2 py-1.5 text-sm"
                  >
                    {ops.map((o) => (
                      <option key={o.value} value={o.value}>
                        {o.label}
                      </option>
                    ))}
                  </select>
                  <input
                    value={cond.value}
                    onChange={(e) => updateCondition(i, { value: e.target.value })}
                    placeholder="value"
                    className="flex-1 bg-zinc-800 border border-zinc-700 rounded px-2 py-1.5 text-sm"
                  />
                  <button
                    type="button"
                    onClick={() => removeCondition(i)}
                    className="text-zinc-500 hover:text-red-400 text-lg leading-none px-1"
                  >
                    ×
                  </button>
                </div>
              );
            })}
            {conditions.length === 0 && (
              <p className="text-xs text-zinc-600">No conditions — rule will match ALL transactions.</p>
            )}
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="block text-xs text-zinc-500 mb-1">Set Category (optional)</label>
              <select
                value={actions.set_category || ""}
                onChange={(e) => setActions({ ...actions, set_category: e.target.value || undefined })}
                className="w-full bg-zinc-800 border border-zinc-700 rounded-lg px-3 py-2 text-sm"
              >
                <option value="">— no change —</option>
                {CATEGORIES.map((c) => (
                  <option key={c} value={c}>
                    {formatCategory(c)}
                  </option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-xs text-zinc-500 mb-1">Set Merchant (optional)</label>
              <input
                value={actions.set_merchant || ""}
                onChange={(e) => setActions({ ...actions, set_merchant: e.target.value || undefined })}
                placeholder="Normalized name"
                className="w-full bg-zinc-800 border border-zinc-700 rounded-lg px-3 py-2 text-sm"
              />
            </div>
          </div>

          <div>
            <label className="block text-xs text-zinc-500 mb-1">Add Tags (optional)</label>
            <div className="flex flex-wrap gap-2">
              {tags.map((tag) => {
                const selected = (actions.add_tag_ids || []).includes(tag.id);
                return (
                  <button
                    key={tag.id}
                    type="button"
                    onClick={() => {
                      const ids = actions.add_tag_ids || [];
                      setActions({
                        ...actions,
                        add_tag_ids: selected ? ids.filter((id) => id !== tag.id) : [...ids, tag.id],
                      });
                    }}
                    className={`px-2 py-1 rounded text-xs border transition-colors ${
                      selected ? "border-transparent text-white" : "border-zinc-700 text-zinc-400"
                    }`}
                    style={selected ? { backgroundColor: tag.color } : {}}
                  >
                    {tag.name}
                  </button>
                );
              })}
              {tags.length === 0 && <p className="text-xs text-zinc-600">No tags created yet.</p>}
            </div>
          </div>

          <div className="flex items-end gap-4">
            <div>
              <label className="block text-xs text-zinc-500 mb-1">Priority</label>
              <input
                type="number"
                value={priority}
                onChange={(e) => setPriority(Number(e.target.value))}
                className="w-24 bg-zinc-800 border border-zinc-700 rounded-lg px-3 py-2 text-sm"
              />
            </div>
            <button
              type="submit"
              disabled={createRule.isPending}
              className="px-6 py-2 bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg text-sm font-medium disabled:opacity-50"
            >
              {createRule.isPending ? "Creating..." : "Create Rule"}
            </button>
          </div>
        </form>
      )}

      {isLoading ? (
        <p className="text-zinc-500 text-sm">Loading rules...</p>
      ) : rules.length === 0 ? (
        <p className="text-zinc-500 text-sm">No rules yet. Create one to auto-classify transactions.</p>
      ) : (
        <div className="space-y-3">
          {rules.map((rule) => {
            const conds = Array.isArray(rule.conditions) ? rule.conditions : [];
            const acts =
              rule.actions && typeof rule.actions === "object" ? (rule.actions as Actions) : {};
            return (
              <div key={rule.id} className="bg-zinc-900 border border-zinc-700 rounded-xl p-4">
                <div className="flex items-start justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-3 mb-1">
                      <span className="font-medium text-sm">{rule.name}</span>
                      <span className="text-xs text-zinc-500">priority: {rule.priority}</span>
                    </div>
                    <p className="text-xs text-zinc-400">
                      {conds.length > 0 ? conds.map(humanCondition).join(" AND ") : "(matches all)"}
                    </p>
                    <p className="text-xs text-zinc-500 mt-1">{humanAction(acts, tagNames)}</p>
                  </div>
                  <div className="flex items-center gap-3 shrink-0">
                    <button
                      onClick={() => updateRule.mutate({ id: rule.id, enabled: !rule.enabled })}
                      className={`relative inline-flex h-5 w-9 rounded-full transition-colors ${
                        rule.enabled ? "bg-indigo-600" : "bg-zinc-700"
                      }`}
                    >
                      <span
                        className={`inline-block h-4 w-4 rounded-full bg-white shadow transform transition-transform mt-0.5 ${
                          rule.enabled ? "translate-x-4" : "translate-x-0.5"
                        }`}
                      />
                    </button>
                    <button
                      onClick={() => {
                        if (confirm("Delete this rule?")) deleteRule.mutate(rule.id);
                      }}
                      className="text-zinc-500 hover:text-red-400 text-sm"
                    >
                      Delete
                    </button>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
