import { useState } from "react";
import { data, Form, Link, redirect, useActionData, useLoaderData } from "react-router";
import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { getArtistById, getArtistLinks, getIpAddress, updateArtist } from "~/lib/db.server";

export async function loader({ params }: LoaderFunctionArgs) {
  const artist = getArtistById(params.uuid!);
  if (!artist) throw data("Not found", { status: 404 });
  const links = getArtistLinks(artist.id);
  return { artist, links };
}

export async function action({ params, request }: ActionFunctionArgs) {
  const artist = getArtistById(params.uuid!);
  if (!artist) throw data("Not found", { status: 404 });

  const fd = await request.formData();
  const name = (fd.get("name") as string).trim();
  const slug = (fd.get("slug") as string).trim();
  const message = (fd.get("message") as string).trim();
  const links: { label: string; url: string }[] = JSON.parse(
    (fd.get("links") as string) || "[]"
  );

  const errors: Record<string, string> = {};
  if (!name) errors.name = "必須です";
  if (!slug) errors.slug = "必須です";
  if (!message) errors.message = "必須です";
  if (Object.keys(errors).length > 0) return { errors };

  try {
    updateArtist(artist.id, { slug, name, links, message, ip_address: getIpAddress(request) });
  } catch (e) {
    if (e instanceof Error && e.message.includes("UNIQUE constraint failed: artists.slug")) {
      return { errors: { slug: "このslugは既に使用されています" } };
    }
    throw e;
  }
  return redirect(`/artists/of/${artist.id}`);
}

function toSlug(s: string) {
  return s.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^\w぀-ヿ一-鿿＀-￯-]/g, "").replace(/^-+|-+$/g, "");
}

export default function ArtistEdit() {
  const { artist, links: initLinks } = useLoaderData<typeof loader>();
  const actionData = useActionData<typeof action>();
  const errors = actionData?.errors ?? {};

  const [name, setName] = useState(artist.name);
  const [slug, setSlug] = useState(artist.slug);
  const [slugManual, setSlugManual] = useState(true);
  const [links, setLinks] = useState(initLinks.map((l) => ({ label: l.label, url: l.url })));

  return (
    <main className="max-w-3xl mx-auto px-4 py-8">
      <div className="flex items-center gap-3 mb-6">
        <Link
          to={`/artists/of/${artist.id}`}
          className="text-gray-400 hover:text-gray-200 transition-colors"
        >
          ←
        </Link>
        <h1 className="text-xl font-semibold">Edit Artist</h1>
      </div>

      <Form method="post" className="space-y-5">
        <input type="hidden" name="links" value={JSON.stringify(links)} />

        <div>
          <label className="block text-sm font-medium text-gray-300 mb-1">
            名前 <span className="text-red-400">*</span>
          </label>
          <input
            name="name"
            value={name}
            onChange={(e) => {
              setName(e.target.value);
              if (!slugManual) setSlug(toSlug(e.target.value));
            }}
            className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500"
          />
          {errors.name && <p className="text-red-400 text-sm mt-1">{errors.name}</p>}
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-300 mb-1">
            Slug <span className="text-red-400">*</span>
          </label>
          <input
            name="slug"
            value={slug}
            onChange={(e) => { setSlugManual(true); setSlug(e.target.value); }}
            className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500 font-mono text-sm"
          />
          {errors.slug && <p className="text-red-400 text-sm mt-1">{errors.slug}</p>}
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-300 mb-2">リンク</label>
          <div className="space-y-2">
            {links.map((link, i) => (
              <div key={i} className="flex gap-2">
                <input
                  value={link.label}
                  onChange={(e) => setLinks(links.map((l, idx) => idx === i ? { ...l, label: e.target.value } : l))}
                  placeholder="ラベル (例: X)"
                  className="w-28 bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500 text-sm"
                />
                <input
                  value={link.url}
                  onChange={(e) => setLinks(links.map((l, idx) => idx === i ? { ...l, url: e.target.value } : l))}
                  placeholder="https://..."
                  className="flex-1 bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500 text-sm"
                />
                <button
                  type="button"
                  onClick={() => setLinks(links.filter((_, idx) => idx !== i))}
                  className="text-gray-500 hover:text-red-400 px-2 transition-colors"
                >
                  ×
                </button>
              </div>
            ))}
          </div>
          <button
            type="button"
            onClick={() => setLinks([...links, { label: "", url: "" }])}
            className="mt-2 text-blue-400 hover:text-blue-300 text-sm transition-colors"
          >
            + リンクを追加
          </button>
        </div>

        <div>
          <label className="block text-sm font-medium text-gray-300 mb-1">
            更新メッセージ <span className="text-red-400">*</span>
          </label>
          <input
            name="message"
            placeholder="例: SNSリンク追加"
            className="w-full bg-gray-800 border border-gray-700 rounded px-3 py-2 text-gray-100 focus:outline-none focus:border-blue-500"
          />
          {errors.message && <p className="text-red-400 text-sm mt-1">{errors.message}</p>}
        </div>

        <div className="flex gap-3 pt-2">
          <button
            type="submit"
            className="bg-blue-600 hover:bg-blue-500 text-white px-4 py-2 rounded font-medium transition-colors"
          >
            保存
          </button>
          <Link
            to={`/artists/of/${artist.id}`}
            className="bg-gray-800 hover:bg-gray-700 text-gray-300 px-4 py-2 rounded transition-colors"
          >
            キャンセル
          </Link>
        </div>
      </Form>
    </main>
  );
}
