import { useEffect, useState, type ReactElement } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { Layout } from "@/components/layout/Layout";
import {
  FormField,
  FormSelect,
  FormTextArea,
  PrimaryButton,
  SecondaryButton,
  FormSlider,
  FormTagInput
} from "@/components/shared";
import { Plus, Trash2, ArrowLeft } from "lucide-react";
import { aiService } from "@/services/ai-service";
import { showToast } from "@/utils/toast";
import { useForm, useFieldArray, Controller } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { cn } from "@/lib/utils";
import type { AIProviderInfo } from "@/types/ai";

const variableSchema = z.object({
  name: z.string().min(1, "Variable name is required").max(100),
  type: z.enum(["string", "number", "boolean", "array"]),
  required: z.boolean(),
  default: z.string().optional(),
});

const promptSchema = z.object({
  name: z.string().min(1, "Name is required").max(255),
  description: z.string().optional(),
  use_case: z.string().min(1, "Use case is required").max(100),
  system_message: z.string().optional(),
  user_template: z.string().min(1, "User template is required").max(50000),
  provider: z.string().optional(),
  model: z.string().optional(),
  temperature: z.number().min(0).max(2),
  max_tokens: z.number().int().min(1).max(128000),
  tags: z.array(z.string()),
  is_default: z.boolean(),
  variables: z.array(variableSchema),
  change_notes: z.string().optional(),
});

type PromptFormData = z.infer<typeof promptSchema>;

const PromptEdit = (): ReactElement => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
  const [apiProviders, setApiProviders] = useState<AIProviderInfo[]>([]);
  const [currentVersion, setCurrentVersion] = useState<number>(1);

  const {
    control,
    handleSubmit,
    setValue,
    watch,
    reset,
    formState: { errors },
  } = useForm<PromptFormData>({
    resolver: zodResolver(promptSchema),
    defaultValues: {
      name: "",
      description: "",
      use_case: "",
      system_message: "",
      user_template: "",
      provider: "",
      model: "",
      temperature: 0.7,
      max_tokens: 2048,
      tags: [],
      is_default: false,
      variables: [],
      change_notes: "",
    },
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: "variables",
  });

  const selectedProvider = watch("provider");

  const providersOptions = apiProviders.map((p) => ({
    value: p.name,
    label: p.displayName || p.name,
  }));

  const providerDetail = apiProviders.find((p) => p.name === selectedProvider);
  const modelsOptions = (providerDetail?.models || []).map((m) => ({
    value: m,
    label: m,
  }));

  useEffect(() => {
    const loadData = async (): Promise<void> => {
      if (!id) return;
      try {
        setIsLoading(true);
        const [providerData, promptData] = await Promise.all([
          aiService.getProviders(),
          aiService.getPrompt(id),
        ]);

        setApiProviders(providerData);

        reset({
          name: promptData.name,
          description: promptData.description || "",
          use_case: promptData.useCase,
          system_message: promptData.systemMessage || "",
          user_template: promptData.template,
          provider: promptData.defaultParameters?.provider || "",
          model: promptData.defaultParameters?.model || "",
          temperature: promptData.defaultParameters?.temperature ?? 0.7,
          max_tokens: promptData.defaultParameters?.max_tokens ?? 2048,
          tags: promptData.tags || [],
          is_default: promptData.isDefault || false,
          variables: (promptData.variables || []).map((v) => ({
            name: v.name,
            type: v.type || "string",
            required: !!v.required,
            default: v.default ? String(v.default) : "",
          })),
          change_notes: "",
        });
        setCurrentVersion(promptData.version || 1);
      } catch (err: unknown) {
        showToast.error(
          (err as { response?: { data?: { error?: { message?: string } } } })
            ?.response?.data?.error?.message ||
            "Failed to load prompt data",
        );
        navigate("/tenant/ai/prompts");
      } finally {
        setIsLoading(false);
      }
    };
    void loadData();
  }, [id, reset, navigate]);

  const onFormSubmit = async (data: PromptFormData): Promise<void> => {
    if (!id) return;
    const parsedTags = data.tags || [];

    const sanitizedVariables = data.variables
      ?.filter((v) => v.name.trim())
      .map((v) => ({
        name: v.name.trim(),
        type: v.type,
        required: v.required,
        ...(v.default?.trim() ? { default: v.default.trim() } : {}),
      }));

    setIsSubmitting(true);
    try {
      await aiService.updatePrompt(id, {
        name: data.name.trim(),
        description: data.description?.trim() || undefined,
        use_case: data.use_case.trim(),
        system_message: data.system_message?.trim() || undefined,
        user_template: data.user_template,
        model: data.model || undefined,
        provider: data.provider || undefined,
        temperature: data.temperature,
        max_tokens: data.max_tokens,
        variables: sanitizedVariables,
        tags: parsedTags,
        is_default: data.is_default,
        change_notes: data.change_notes,
      });
      showToast.success("Prompt updated successfully");
      navigate("/tenant/ai/prompts");
    } catch (err: unknown) {
      showToast.error(
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || "Failed to update prompt",
      );
    } finally {
      setIsSubmitting(false);
    }
  };

  if (isLoading) {
    return (
      <Layout currentPage="Edit Prompt">
        <div className="flex items-center justify-center min-h-[400px]">
          <div className="flex flex-col items-center gap-3">
            <div className="w-10 h-10 border-4 border-gray-200 border-t-[#112868] rounded-full animate-spin"></div>
            <p className="text-sm text-gray-500">Loading prompt details...</p>
          </div>
        </div>
      </Layout>
    );
  }

  return (
    <Layout
      currentPage="Edit Prompt"
      pageHeader={{
        title: "Edit Prompt",
        description: "Modify prompt template and configuration settings.",
        action: (
          <div className="flex gap-2">
            <SecondaryButton onClick={() => navigate("/tenant/ai/prompts")}>
              Cancel
            </SecondaryButton>
            <PrimaryButton onClick={handleSubmit(onFormSubmit)} disabled={isSubmitting}>
              {isSubmitting ? "Updating..." : "Update Prompt"}
            </PrimaryButton>
          </div>
        ),
      }}
    >
      <div className="mb-4">
        <button
          onClick={() => navigate("/tenant/ai/prompts")}
          className="flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-900 transition-colors"
        >
          <ArrowLeft className="w-4 h-4" />
          Back to list
        </button>
      </div>

      <form
        onSubmit={handleSubmit(onFormSubmit)}
        className="flex items-start gap-6"
      >
        {/* LEFT SIDE */}
        <div className="flex flex-col gap-6 flex-[2]">
          {/* General Information */}
          <div className="bg-white border border-gray-300 rounded-lg shadow-sm p-4 space-y-4">
            <h2 className="text-sm font-semibold text-gray-800">
              General Information
            </h2>

            <Controller
              name="name"
              control={control}
              render={({ field }) => (
                <FormField
                  {...field}
                  label="Template Name"
                  required
                  placeholder="e.g., Code Review Assistant"
                  helperText="Max 255 characters. Must be unique per tenant and version"
                  error={errors.name?.message}
                />
              )}
            />

            <Controller
              name="description"
              control={control}
              render={({ field }) => (
                <FormTextArea
                  {...field}
                  label="Description"
                  placeholder="Describe what this prompt template is used for..."
                  helperText="Optional template summary to explain the purpose and expected usage."
                  error={errors.description?.message}
                />
              )}
            />
          </div>

          {/* Prompt Content */}
          <div className="bg-white border border-gray-300 rounded-lg shadow-sm p-4 space-y-4">
            <h2 className="text-sm font-semibold text-gray-800">
              Prompt Content
            </h2>

            <Controller
              name="system_message"
              control={control}
              render={({ field }) => (
                <FormTextArea
                  {...field}
                  label="System Message"
                  placeholder="You are an expert software engineer..."
                  error={errors.system_message?.message}
                  helperText="Optional system prompt that is added before the template content to guide assistant behavior."
                />
              )}
            />

            <Controller
              name="user_template"
              control={control}
              render={({ field }) => (
                <FormTextArea
                  {...field}
                  label="User Template"
                  required
                  placeholder={
                    "Summarize the following document:\n{{document_text}}\nFocus on: {{focus_areas}}"
                  }
                  error={errors.user_template?.message}
                  helperText={
                    <>
                      Use <code className="text-[#112868] font-bold">{"{{variable_name}}"}</code> for dynamic inputs.
                      <p className="mt-1.5 text-amber-600 font-medium flex items-center gap-1.5">
                        <span className="w-1.5 h-1.5 rounded-full bg-amber-500 animate-pulse" />
                        Updating this template will create a new version (v{currentVersion + 1})
                      </p>
                    </>
                  }
                />
              )}
            />

            <Controller
              name="change_notes"
              control={control}
              render={({ field }) => (
                <FormTextArea
                  {...field}
                  label="Change Notes"
                  placeholder="e.g. Optimized the system message for better accuracy, added new variables..."
                  helperText="Describe what changed in this version. This will be visible in the version history."
                  error={errors.change_notes?.message}
                />
              )}
            />

            {/* Variables Section */}
            <div className="bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden">
              <div className="p-4 border-b border-gray-100 flex items-center justify-between">
                <h3 className="text-sm font-semibold text-gray-800">
                  Variables Configuration
                </h3>
                <PrimaryButton
                  onClick={() =>
                    append({
                      name: "",
                      type: "string",
                      required: false,
                      default: "",
                    })
                  }
                  size="small"
                  className="h-8 py-0"
                >
                  <Plus className="w-4 h-4 mr-1" />
                  Add Variable
                </PrimaryButton>
              </div>

              <div className="p-4">
                {fields.length > 0 && (
                  <div className="grid grid-cols-[1fr_120px_1fr_80px_40px] gap-4 px-2 mb-2">
                    <span className="text-[11px] font-bold text-gray-400 uppercase tracking-wider">
                      Variable Name
                    </span>
                    <span className="text-[11px] font-bold text-gray-400 uppercase tracking-wider text-center">
                      Type
                    </span>
                    <span className="text-[11px] font-bold text-gray-400 uppercase tracking-wider">
                      Default Value
                    </span>
                    <span className="text-[11px] font-bold text-gray-400 uppercase tracking-wider text-center">
                      Required
                    </span>
                    <span></span>
                  </div>
                )}

                <div className="space-y-3">
                  {fields.map((field, index) => (
                    <div
                      key={field.id}
                      className="grid grid-cols-[1fr_120px_1fr_80px_40px] gap-4 items-start border-b border-gray-50 pb-3 last:border-0 last:pb-0"
                    >
                      <Controller
                        name={`variables.${index}.name`}
                        control={control}
                        render={({ field }) => (
                          <div className="space-y-1">
                            <input
                              {...field}
                              placeholder="e.g context"
                              className={cn(
                                "h-10 w-full px-3.5 py-1 bg-white border border-[rgba(0,0,0,0.08)] rounded-md text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#112868]/20 focus-visible:border-[#112868]",
                                errors.variables?.[index]?.name &&
                                  "border-red-500",
                              )}
                            />
                            {errors.variables?.[index]?.name && (
                              <p className="text-[10px] text-red-500">
                                {errors.variables?.[index]?.name?.message}
                              </p>
                            )}
                          </div>
                        )}
                      />
                      <Controller
                        name={`variables.${index}.type`}
                        control={control}
                        render={({ field }) => (
                          <div className="h-10 flex flex-col justify-center">
                            <FormSelect
                              label=""
                              className="pb-0"
                              value={field.value}
                              onValueChange={field.onChange}
                              options={[
                                { value: "string", label: "String" },
                                { value: "number", label: "Number" },
                                { value: "boolean", label: "Boolean" },
                                { value: "array", label: "Array" },
                              ]}
                              error={errors.variables?.[index]?.type?.message}
                            />
                          </div>
                        )}
                      />
                      <Controller
                        name={`variables.${index}.default`}
                        control={control}
                        render={({ field }) => (
                          <div className="space-y-1">
                            <input
                              {...field}
                              placeholder="Enter default value"
                              className={cn(
                                "h-10 w-full px-3.5 py-1 bg-white border border-[rgba(0,0,0,0.08)] rounded-md text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#112868]/20 focus-visible:border-[#112868]",
                                errors.variables?.[index]?.default &&
                                  "border-red-500",
                              )}
                            />
                            {errors.variables?.[index]?.default && (
                              <p className="text-[10px] text-red-500">
                                {errors.variables?.[index]?.default?.message}
                              </p>
                            )}
                          </div>
                        )}
                      />
                      <div className="h-10 flex items-center justify-center">
                        <Controller
                          name={`variables.${index}.required`}
                          control={control}
                          render={({ field }) => (
                            <div
                              className={cn(
                                "w-10 h-5 rounded-full relative transition-colors duration-200 cursor-pointer",
                                field.value ? "bg-[#084cc8]" : "bg-gray-200",
                              )}
                              onClick={() => field.onChange(!field.value)}
                            >
                              <div
                                className={cn(
                                  "absolute top-1 left-1 w-3 h-3 bg-white rounded-full transition-transform duration-200 shadow-sm",
                                  field.value && "translate-x-5",
                                )}
                              />
                            </div>
                          )}
                        />
                      </div>
                      <button
                        type="button"
                        onClick={() => remove(index)}
                        className="h-10 flex items-center justify-center text-gray-400 hover:text-red-500 transition-colors"
                      >
                        <Trash2 className="w-5 h-5" />
                      </button>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* RIGHT SIDE (Sidebar) */}
        <div className="flex flex-col gap-6 flex-1 max-w-[320px] w-full">
          {/* Settings */}
          <div className="bg-white border border-gray-300 rounded-lg shadow-sm p-4 space-y-4">
            <h2 className="text-sm font-semibold text-gray-800">Settings</h2>

            <Controller
              name="use_case"
              control={control}
              render={({ field }) => (
                <FormField
                  {...field}
                  label="Use Case"
                  required
                  placeholder="e.g. document_analysis"
                  error={errors.use_case?.message}
                />
              )}
            />

            <div className="space-y-2 pt-2">
              <label className="text-[13px] font-semibold text-[#0e1b2a]">Is Default</label>
              <div className="flex items-center gap-3">
                <Controller
                  name="is_default"
                  control={control}
                  render={({ field }) => (
                    <div
                      className={cn(
                        "w-10 h-5 rounded-full relative transition-colors duration-200 cursor-pointer",
                        field.value ? "bg-[#112868]" : "bg-gray-200",
                      )}
                      onClick={() => field.onChange(!field.value)}
                    >
                      <div
                        className={cn(
                          "absolute top-1 left-1 w-3 h-3 rounded-full transition-transform duration-200 shadow-sm",
                          field.value ? "translate-x-5 bg-[#00cfd5]" : "bg-white",
                        )}
                      />
                    </div>
                  )}
                />
                <span className="text-[13px] text-gray-500 font-medium">Make default for this use case</span>
              </div>
            </div>
          </div>

          {/* Model Config */}
          <div className="bg-white border border-gray-300 rounded-lg shadow-sm p-4 space-y-2">
            <h2 className="text-sm font-semibold text-gray-800 mb-2">
              Model Configuration
            </h2>

            <Controller
              name="provider"
              control={control}
              render={({ field }) => (
                <FormSelect
                  label="Provider"
                  value={field.value || ""}
                  onValueChange={(val) => {
                    field.onChange(val);
                    const pDetail = apiProviders.find((p) => p.name === val);
                    if (pDetail && pDetail.defaultModel) {
                      setValue("model", pDetail.defaultModel);
                    } else if (pDetail && pDetail.models && pDetail.models.length > 0) {
                      setValue("model", pDetail.models[0]);
                    } else {
                      setValue("model", "");
                    }
                  }}
                  options={providersOptions}
                  error={errors.provider?.message}
                />
              )}
            />

            <Controller
              name="model"
              control={control}
              render={({ field }) => (
                <FormSelect
                  label="Model"
                  value={field.value || ""}
                  onValueChange={field.onChange}
                  options={modelsOptions}
                  error={errors.model?.message}
                />
              )}
            />

            <Controller
              name="temperature"
              control={control}
              render={({ field }) => (
                <FormSlider
                  {...field}
                  label="Temperature"
                  min={0}
                  max={2}
                  step={0.1}
                  helperText="Lower values make output more deterministic"
                  error={errors.temperature?.message}
                />
              )}
            />

            <Controller
              name="max_tokens"
              control={control}
              render={({ field }) => (
                <FormSlider
                  {...field}
                  label="Max Tokens"
                  min={1}
                  max={5000}
                  step={1}
                  helperText="Maximum response token budget."
                  error={errors.max_tokens?.message}
                />
              )}
            />
          </div>

          {/* Organization */}
          <div className="bg-white border border-gray-300 rounded-lg shadow-sm p-4 space-y-4">
            <h2 className="text-sm font-semibold text-gray-800">
              Organization
            </h2>
            <Controller
              name="tags"
              control={control}
              render={({ field }) => (
                <FormTagInput
                  label="Tags (Press enter to add)"
                  value={field.value || []}
                  onChange={field.onChange}
                  error={errors.tags?.message}
                />
              )}
            />
          </div>
        </div>
      </form>
    </Layout>
  );
};

export default PromptEdit;
