import { useMutation, useQueryClient } from "@tanstack/react-query"
import { canUseWritingCheck, recordWritingCheckUsage } from "@/utils/rate-limiter"
import { useAuthStore } from "@/store/auth-store"
import { saveWritingSubmission, countTodayWritingSubmissions } from "@/lib/progress-service"
import type { WritingFeedback } from "@/types"

const AUTH_DAILY_LIMIT = 10
const GUEST_DAILY_LIMIT = 3

// Resolve env at runtime — production injects window.__ENV__ via docker/entrypoint.sh,
// dev reads from Vite's import.meta.env. Must match src/lib/supabase.ts.
function resolveSupabaseEnv() {
  const runtime = (window as unknown as { __ENV__?: Record<string, string> }).__ENV__ ?? {}
  const url = runtime.VITE_SUPABASE_URL || import.meta.env.VITE_SUPABASE_URL
  const key =
    runtime.VITE_SUPABASE_ANON_KEY ||
    runtime.VITE_SUPABASE_PUBLISHABLE_KEY ||
    import.meta.env.VITE_SUPABASE_ANON_KEY ||
    import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY
  return { url: url as string | undefined, key: key as string | undefined }
}

// Calls the writing-check-dbiz Supabase edge function.
// SSE format emitted by the function: data: {"text":"..."} | data: [DONE]
async function callEdgeFunction(
  content: string,
  onChunk?: (text: string) => void,
): Promise<WritingFeedback> {
  const { url, key } = resolveSupabaseEnv()
  if (!url || !key) {
    throw new Error("Supabase chưa được cấu hình. Vui lòng kiểm tra biến môi trường.")
  }
  const res = await fetch(`${url}/functions/v1/writing-check-dbiz`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${key}`,
      apikey: key,
    },
    body: JSON.stringify({ content }),
  })

  if (!res.ok) {
    const body = await res.json().catch(() => ({}))
    throw new Error(body?.error ?? "Đã có lỗi khi chấm bài. Vui lòng thử lại.")
  }

  const reader = res.body!.getReader()
  const decoder = new TextDecoder()
  let buffer = ""
  let accumulated = ""

  while (true) {
    const { done, value } = await reader.read()
    if (done) break

    buffer += decoder.decode(value, { stream: true })
    const lines = buffer.split("\n")
    buffer = lines.pop() ?? ""

    for (const line of lines) {
      if (!line.startsWith("data: ")) continue
      const payload = line.slice(6).trim()
      if (payload === "[DONE]") continue

      let chunk: { text?: string; error?: string }
      try {
        chunk = JSON.parse(payload)
      } catch {
        continue
      }

      if (chunk.error) throw new Error(chunk.error)

      const text = chunk.text ?? ""
      if (text) {
        accumulated += text
        onChunk?.(text)
      }
    }
  }

  const start = accumulated.indexOf("{")
  const end = accumulated.lastIndexOf("}")
  if (start === -1 || end === -1) {
    throw new Error("Phản hồi từ AI không hợp lệ. Vui lòng thử lại.")
  }

  const raw = JSON.parse(accumulated.slice(start, end + 1))

  const toArray = (v: unknown): string[] => {
    if (Array.isArray(v)) return v
    if (typeof v === "string" && v.length > 0) return [v]
    return []
  }

  return {
    ...raw,
    grammar: toArray(raw.grammar),
    vocabulary: toArray(raw.vocabulary),
    improvedVersion: raw.improved_version ?? raw.improvedVersion ?? "",
  } as WritingFeedback
}

export function useWritingCheck() {
  const queryClient = useQueryClient()
  return useMutation({
    mutationFn: async ({
      content,
      onChunk,
    }: {
      content: string
      onChunk?: (text: string) => void
    }): Promise<WritingFeedback> => {
      const user = useAuthStore.getState().user

      if (user) {
        const usedToday = await countTodayWritingSubmissions(user.id)
        if (usedToday >= AUTH_DAILY_LIMIT) {
          throw new Error(`Bạn đã dùng hết ${AUTH_DAILY_LIMIT} lần kiểm tra hôm nay. Quay lại vào ngày mai!`)
        }
      } else {
        if (!canUseWritingCheck()) {
          throw new Error(`Bạn đã dùng hết ${GUEST_DAILY_LIMIT} lần kiểm tra hôm nay. Đăng ký để được 10 lần/ngày!`)
        }
      }

      const feedback = await callEdgeFunction(content, onChunk)

      if (user) {
        await saveWritingSubmission(user.id, content, feedback)
        queryClient.invalidateQueries({ queryKey: ["writing-history"] })
      } else {
        recordWritingCheckUsage()
      }

      return feedback
    },
  })
}
