import { useNavigate, useParams } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { toast } from "sonner";
import {
  AlertCircle,
  ArrowLeft,
  ArrowRight,
  ExternalLink,
  Loader2,
  Plus,
  Trash2,
} from "lucide-react";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Skeleton } from "@/components/ui/skeleton";
import { useProject } from "@/hooks/useProjects";
import { useCreateSource, useDeleteSource } from "@/hooks/useSources";

const SOURCE_TYPES = [
  "official",
  "review",
  "blog",
  "news",
  "community",
  "unknown",
] as const;

const sourceSchema = z.object({
  name: z
    .string()
    .min(2, "최소 2자 이상")
    .max(64, "최대 64자")
    .regex(/^[a-zA-Z0-9_-]+$/, "영문/숫자/_/-만 허용"),
  type: z.enum(SOURCE_TYPES),
  base_url: z
    .string()
    .url("올바른 URL 형식이 아닙니다")
    .or(z.literal(""))
    .optional(),
  trust_level: z
    .number({ invalid_type_error: "0~1 사이의 숫자" })
    .min(0)
    .max(1),
  rate_limit_per_minute: z
    .number({ invalid_type_error: "양의 정수" })
    .int()
    .min(1)
    .max(600),
  respect_robots_txt: z.boolean(),
});

type SourceFormValues = z.infer<typeof sourceSchema>;

export default function ConfigureSourcesPage() {
  const navigate = useNavigate();
  const { projectId } = useParams<{ projectId: string }>();
  const { t } = useTranslation();
  const projectName = projectId ?? "";

  const {
    data: project,
    isLoading,
    isError,
    error,
    refetch,
  } = useProject(projectName);

  const createSource = useCreateSource(projectName);
  const deleteSource = useDeleteSource(projectName);

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors, isSubmitting },
  } = useForm<SourceFormValues>({
    resolver: zodResolver(sourceSchema),
    defaultValues: {
      name: "",
      type: "official",
      base_url: "",
      trust_level: 0.7,
      rate_limit_per_minute: 30,
      respect_robots_txt: true,
    },
  });

  const onAddSource = async (values: SourceFormValues) => {
    try {
      await createSource.mutateAsync({
        ...values,
        base_url: values.base_url || null,
      });
      toast.success(
        t("sources.added", "소스가 추가되었습니다: {{name}}", {
          name: values.name,
        }),
      );
      reset();
    } catch (e) {
      toast.error(
        t("sources.addFailed", "추가 실패: {{msg}}", {
          msg: (e as Error).message,
        }),
      );
    }
  };

  const onDelete = async (sourceName: string) => {
    if (
      !confirm(
        t("sources.confirmDelete", "정말 '{{name}}' 소스를 삭제하시겠습니까?", {
          name: sourceName,
        }),
      )
    ) {
      return;
    }
    try {
      await deleteSource.mutateAsync(sourceName);
      toast.success(
        t("sources.deleted", "소스가 삭제되었습니다: {{name}}", {
          name: sourceName,
        }),
      );
    } catch (e) {
      toast.error(
        t("sources.deleteFailed", "삭제 실패: {{msg}}", {
          msg: (e as Error).message,
        }),
      );
    }
  };

  return (
    <div className="mx-auto max-w-5xl px-6 py-10">
      <div className="mb-6 flex items-center gap-3">
        <Button
          variant="ghost"
          size="icon"
          onClick={() => navigate("/")}
          aria-label={t("common.back", "이전")}
        >
          <ArrowLeft className="h-4 w-4" />
        </Button>
        <div className="flex-1">
          <h1 className="text-2xl font-bold tracking-tight">
            {t("sources.title", "참고 소스 설정")}
          </h1>
          {project && (
            <p className="text-sm text-muted-foreground">
              {project.name}{" "}
              <span className="capitalize text-muted-foreground/70">
                · {project.domain}
              </span>
            </p>
          )}
        </div>
        <Button
          onClick={() => navigate(`/crawl/${projectName}`)}
          disabled={!project || (project.sources?.length ?? 0) === 0}
        >
          {t("sources.next", "크롤 진행")}
          <ArrowRight className="h-4 w-4" />
        </Button>
      </div>

      {isError && (
        <Card className="mb-6 border-destructive">
          <CardContent className="flex items-center justify-between gap-3 py-4">
            <div className="flex items-center gap-2 text-sm text-destructive">
              <AlertCircle className="h-4 w-4" />
              <span>{(error as Error).message}</span>
            </div>
            <Button
              variant="outline"
              size="sm"
              type="button"
              onClick={() => refetch()}
            >
              {t("common.retry", "다시 시도")}
            </Button>
          </CardContent>
        </Card>
      )}

      <div className="grid gap-6 lg:grid-cols-[1fr_360px]">
        <section>
          <Card>
            <CardHeader>
              <CardTitle>{t("sources.listTitle", "등록된 소스")}</CardTitle>
              <CardDescription>
                {t(
                  "sources.listDesc",
                  "프로젝트 온톨로지 구축에 사용할 참고 사이트 목록",
                )}
              </CardDescription>
            </CardHeader>
            <CardContent>
              {isLoading && (
                <div className="space-y-3">
                  {Array.from({ length: 3 }).map((_, i) => (
                    <Skeleton key={i} className="h-16" />
                  ))}
                </div>
              )}

              {project && project.sources.length === 0 && (
                <p className="py-8 text-center text-sm text-muted-foreground">
                  {t(
                    "sources.empty",
                    "아직 등록된 소스가 없습니다. 오른쪽 폼에서 추가하세요.",
                  )}
                </p>
              )}

              {project && project.sources.length > 0 && (
                <ul className="divide-y">
                  {project.sources.map((s) => (
                    <li
                      key={s.id}
                      className="flex items-center justify-between gap-4 py-3"
                    >
                      <div className="min-w-0 flex-1">
                        <div className="flex items-center gap-2">
                          <span className="font-medium">{s.name}</span>
                          <span className="rounded bg-secondary px-1.5 py-0.5 text-xs text-secondary-foreground">
                            {s.type}
                          </span>
                          {typeof s.trust_level === "number" && (
                            <span className="text-xs text-muted-foreground">
                              {t("sources.trust", "신뢰도")}{" "}
                              {s.trust_level.toFixed(2)}
                            </span>
                          )}
                        </div>
                        {s.base_url && (
                          <a
                            href={s.base_url}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="mt-1 inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
                          >
                            <ExternalLink className="h-3 w-3" />
                            {s.base_url}
                          </a>
                        )}
                      </div>
                      <Button
                        variant="ghost"
                        size="icon"
                        onClick={() => onDelete(s.name)}
                        disabled={deleteSource.isPending}
                        aria-label={t("sources.delete", "삭제")}
                      >
                        <Trash2 className="h-4 w-4 text-destructive" />
                      </Button>
                    </li>
                  ))}
                </ul>
              )}
            </CardContent>
          </Card>
        </section>

        <aside>
          <Card>
            <CardHeader>
              <CardTitle>{t("sources.addTitle", "소스 추가")}</CardTitle>
              <CardDescription>
                {t("sources.addDesc", "참고할 사이트 정보를 입력하세요")}
              </CardDescription>
            </CardHeader>
            <CardContent>
              <form
                onSubmit={handleSubmit(onAddSource)}
                className="space-y-4"
                noValidate
              >
                <div className="space-y-1.5">
                  <Label htmlFor="src_name">
                    {t("sources.name", "이름")}
                  </Label>
                  <Input
                    id="src_name"
                    placeholder="official_brand_site"
                    {...register("name")}
                  />
                  {errors.name && (
                    <p className="text-xs text-destructive">
                      {errors.name.message}
                    </p>
                  )}
                </div>

                <div className="space-y-1.5">
                  <Label htmlFor="src_type">
                    {t("sources.type", "타입")}
                  </Label>
                  <select
                    id="src_type"
                    className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                    {...register("type")}
                  >
                    {SOURCE_TYPES.map((t) => (
                      <option key={t} value={t}>
                        {t}
                      </option>
                    ))}
                  </select>
                </div>

                <div className="space-y-1.5">
                  <Label htmlFor="src_url">
                    {t("sources.baseUrl", "Base URL")}
                  </Label>
                  <Input
                    id="src_url"
                    placeholder="https://example.com"
                    type="url"
                    {...register("base_url")}
                  />
                  {errors.base_url && (
                    <p className="text-xs text-destructive">
                      {errors.base_url.message}
                    </p>
                  )}
                </div>

                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-1.5">
                    <Label htmlFor="src_trust">
                      {t("sources.trust", "신뢰도")}
                    </Label>
                    <Input
                      id="src_trust"
                      type="number"
                      step="0.05"
                      min={0}
                      max={1}
                      {...register("trust_level", { valueAsNumber: true })}
                    />
                    {errors.trust_level && (
                      <p className="text-xs text-destructive">
                        {errors.trust_level.message}
                      </p>
                    )}
                  </div>
                  <div className="space-y-1.5">
                    <Label htmlFor="src_rate">
                      {t("sources.rateLimit", "rate/분")}
                    </Label>
                    <Input
                      id="src_rate"
                      type="number"
                      min={1}
                      max={600}
                      {...register("rate_limit_per_minute", {
                        valueAsNumber: true,
                      })}
                    />
                    {errors.rate_limit_per_minute && (
                      <p className="text-xs text-destructive">
                        {errors.rate_limit_per_minute.message}
                      </p>
                    )}
                  </div>
                </div>

                <label className="flex items-center gap-2 text-sm">
                  <input
                    type="checkbox"
                    className="h-4 w-4 rounded border-input"
                    {...register("respect_robots_txt")}
                  />
                  <span>
                    {t("sources.respectRobots", "robots.txt 준수")}
                  </span>
                </label>

                <Button
                  type="submit"
                  className="w-full"
                  disabled={isSubmitting || createSource.isPending}
                >
                  {createSource.isPending ? (
                    <Loader2 className="h-4 w-4 animate-spin" />
                  ) : (
                    <Plus className="h-4 w-4" />
                  )}
                  {t("sources.add", "소스 추가")}
                </Button>
              </form>
            </CardContent>
          </Card>
        </aside>
      </div>
    </div>
  );
}
