import * as Icons from "lucide-react"
import { useMemo, useState } from "react"
import { useSuspenseQuery, useMutation, useQueryClient, queryOptions } from "@tanstack/react-query"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"
import { Textarea } from "@/components/ui/textarea"
import { supabase } from "@/auth/supabase"
import { toast } from "sonner"
import ReactMarkdown from 'react-markdown'


/* =====================================================
   Query keys & fetcher
===================================================== */
export const planKeys = {
  root: ["plan"] as const,
  byId: (id: string) => [...planKeys.root, id] as const,
}

export type PlanTextFields = {
  objetivo_general?: string | string[] | null
  sistema_evaluacion?: string | string[] | null
  perfil_ingreso?: string | string[] | null
  perfil_egreso?: string | string[] | null
  competencias_genericas?: string | string[] | null
  competencias_especificas?: string | string[] | null
  indicadores_desempeno?: string | string[] | null
  pertinencia?: string | string[] | null
  prompt?: string | null
}

async function fetchPlanText(planId: string): Promise<PlanTextFields> {
  const { data, error } = await supabase
    .from("plan_estudios")
    .select(
      `objetivo_general, sistema_evaluacion, perfil_ingreso, perfil_egreso,
       competencias_genericas, competencias_especificas, indicadores_desempeno,
       pertinencia, prompt`
    )
    .eq("id", planId)
    .single()
  if (error) throw error
  return (data ?? {}) as PlanTextFields
}

export const planTextOptions = (planId: string) =>
  queryOptions({
    queryKey: planKeys.byId(planId),
    queryFn: () => fetchPlanText(planId),
    staleTime: 60_000,
  })

/* =====================================================
   Color helpers
===================================================== */
function hexToRgb(hex?: string | null): [number, number, number] {
  if (!hex) return [37, 99, 235]
  const h = hex.replace("#", "")
  const v = h.length === 3 ? h.split("").map((c) => c + c).join("") : h
  const n = parseInt(v, 16)
  return [(n >> 16) & 255, (n >> 8) & 255, n & 255]
}
const rgba = (rgb: [number, number, number], a: number) => `rgba(${rgb[0]},${rgb[1]},${rgb[2]},${a})`

/* =====================================================
   Expandable text
===================================================== */
function ExpandableText({ text, mono = false }: { text?: string | string[] | null; mono?: boolean }) {
  const [open, setOpen] = useState(false)
  if (!text || (Array.isArray(text) && text.length === 0)) {
    return <span className="text-neutral-400">—</span>
  }
  const content = Array.isArray(text) ? text.join("\n• ") : text
  const rendered = Array.isArray(text) ? `• ${content}` : content
  return (
    <div>
      <ReactMarkdown>{rendered}</ReactMarkdown>
      {String(rendered).length > 220 && (
        <button onClick={() => setOpen((v) => !v)} className="mt-2 text-xs font-medium text-neutral-600 hover:underline">
          {open ? "Ver menos" : "Ver más"}
        </button>
      )}
    </div>
  )
}

/* =====================================================
   Section panel
===================================================== */
function SectionPanel({ title, icon: Icon, color, children, id }: { title: string; icon: any; color?: string | null; children: React.ReactNode; id: string }) {
  const rgb = hexToRgb(color)
  return (
    <section id={id} className="relative rounded-3xl border overflow-hidden shadow-sm bg-white/70 dark:bg-neutral-900/60">
      <div className="pointer-events-none absolute inset-0 -z-0">
        <div className="absolute -top-20 -left-20 w-[28rem] h-[28rem] rounded-full blur-3xl" style={{ background: `radial-gradient(circle, ${rgba(rgb, 0.2)}, transparent 60%)` }} />
        <div className="absolute -bottom-24 -right-16 w-[24rem] h-[24rem] rounded-full blur-[60px]" style={{ background: `radial-gradient(circle, ${rgba(rgb, 0.14)}, transparent 60%)` }} />
      </div>
      <div className="relative z-10 px-4 py-3 flex items-center gap-2 border-b" style={{ background: `linear-gradient(180deg, ${rgba(rgb, 0.1)}, transparent)` }}>
        <span className="inline-flex items-center justify-center rounded-xl border px-2.5 py-2 bg-white/80" style={{ borderColor: rgba(rgb, 0.25) }}>
          <Icon className="w-4 h-4" />
        </span>
        <h3 className="font-semibold">{title}</h3>
      </div>
      <div className="relative z-10 p-5">{children}</div>
    </section>
  )
}

/* =====================================================
   AcademicSections (con React Query)
===================================================== */
export function AcademicSections({ planId, color }: { planId: string; color?: string | null }) {
  const qc = useQueryClient()
  if(!planId) return <div>Cargando…</div>
  const { data: plan } = useSuspenseQuery(planTextOptions(planId))

  const [editing, setEditing] = useState<null | { key: keyof PlanTextFields; title: string }>(null)
  const [draft, setDraft] = useState("")

  // --- mutation con actualización optimista ---
  const updateField = useMutation({
    mutationFn: async ({ key, value }: { key: keyof PlanTextFields; value: string | string[] | null }) => {
      const payload: Record<string, any> = { [key]: value }
      const { error } = await supabase.from("plan_estudios").update(payload).eq("id", planId)
      if (error) throw error
      return payload
    },
    onMutate: async ({ key, value }) => {
      await qc.cancelQueries({ queryKey: planKeys.byId(planId) })
      const prev = qc.getQueryData<PlanTextFields>(planKeys.byId(planId))
      qc.setQueryData<PlanTextFields>(planKeys.byId(planId), (old) => ({ ...(old ?? {}), [key]: value }))
      return { prev }
    },
    onError: (e, _vars, ctx) => {
      if (ctx?.prev) qc.setQueryData(planKeys.byId(planId), ctx.prev)
      toast.error((e as any)?.message || "No se pudo guardar 😓")
    },
    onSuccess: () => {
      toast.success("Guardado ✅")
    },
    onSettled: async () => {
      await qc.invalidateQueries({ queryKey: planKeys.byId(planId) })
    },
  })

  const sections = useMemo(
    () => [
      { id: "sec-obj", title: "Objetivo general", icon: Icons.Target, key: "objetivo_general" as const, mono: false },
      { id: "sec-eval", title: "Sistema de evaluación", icon: Icons.CheckCircle2, key: "sistema_evaluacion" as const, mono: false },
      { id: "sec-ing", title: "Perfil de ingreso", icon: Icons.UserPlus, key: "perfil_ingreso" as const, mono: false },
      { id: "sec-egr", title: "Perfil de egreso", icon: Icons.GraduationCap, key: "perfil_egreso" as const, mono: false },
      { id: "sec-cg", title: "Competencias genéricas", icon: Icons.Sparkles, key: "competencias_genericas" as const, mono: false },
      { id: "sec-ce", title: "Competencias específicas", icon: Icons.Cog, key: "competencias_especificas" as const, mono: false },
      { id: "sec-ind", title: "Indicadores de desempeño", icon: Icons.LineChart, key: "indicadores_desempeno" as const, mono: false },
      { id: "sec-per", title: "Pertinencia", icon: Icons.Lightbulb, key: "pertinencia" as const, mono: false },
      { id: "sec-prm", title: "Prompt (origen)", icon: Icons.Code2, key: "prompt" as const, mono: true },
    ],
    []
  )

  return (
    <>
      <div className="grid gap-5 md:grid-cols-2">
        {sections.map((s) => {
          const text = plan[s.key] ?? null
          return (
            <SectionPanel key={s.id} id={s.id} title={s.title} icon={s.icon} color={color}>
              <ExpandableText text={text} mono={s.mono} />
              <div className="mt-4 flex flex-wrap gap-2">
                <Button
                  variant="outline"
                  size="sm"
                  disabled={!text || (Array.isArray(text) && text.length === 0)}
                  onClick={() => {
                    const toCopy = Array.isArray(text) ? text.join("\n") : (text ?? "")
                    if (toCopy) navigator.clipboard.writeText(toCopy)
                  }}
                >
                  Copiar
                </Button>
                {s.key !== "prompt" && 
                  (<Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                      const current = Array.isArray(text) ? text.join("\n") : (text ?? "")
                      setEditing({ key: s.key, title: s.title })
                      setDraft(current)
                    }}
                  >
                    Editar
                  </Button>)}
              </div>
            </SectionPanel>
          )
        })}
      </div>

      {/* Diálogo de edición */}
      <Dialog open={!!editing} onOpenChange={(o) => { if (!o) setEditing(null) }}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle className="font-mono" >{editing ? `Editar: ${sections.find((x) => x.key === editing.key)?.title}` : ""}</DialogTitle>
          </DialogHeader>
          <Textarea value={draft} onChange={(e) => setDraft(e.target.value)} className={`min-h-[260px] ${editing?.key === "prompt" ? "font-mono" : ""}`} placeholder="Escribe aquí…" />
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditing(null)}>Cancelar</Button>
            <Button
              onClick={() => {
                if (!editing) return
                updateField.mutate({ key: editing.key, value: draft })
                setEditing(null)
              }}
              disabled={updateField.isPending}
            >
              {updateField.isPending ? "Guardando…" : "Guardar"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  )
}
