import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
import { ResponsesTable, type DisplayRow } from './responses-table'
import { SurveySelect } from './survey-select'
import { SignOutButton } from '../sign-out-button'
import { formatDate, renderValue } from './admin-format'

export const dynamic = 'force-dynamic'

const PAGE_SIZE = 50
const PROMPT_MAX_LEN = 60

interface AllowedQuestion {
  id: string
  code: string
  prompt: string
  type: string
  position: number
}

interface AnswerRow {
  value: unknown
  question_id: string
}

interface ResponseRow {
  id: string
  submitted_at: string
  qi_zone: string | null
  qi_sector: string | null
  answers: AnswerRow[]
}

interface SurveyOption {
  id: string
  title: string
}

async function getSupabaseSession() {
  const cookieStore = await cookies()
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options)
            )
          } catch {
            // Server Component — no puede mutar cookies, se ignora
          }
        },
      },
    }
  )
}

function truncate(text: string, max = PROMPT_MAX_LEN): string {
  return text.length > max ? `${text.slice(0, max)}...` : text
}

function pageHref(surveyId: string | undefined, page: number): string {
  const params = new URLSearchParams()
  if (surveyId) params.set('survey_id', surveyId)
  params.set('page', String(page))
  return `/admin/responses?${params.toString()}`
}

export default async function AdminResponsesPage({
  searchParams,
}: {
  searchParams: Promise<{ survey_id?: string; page?: string }>
}) {
  const { survey_id: surveyId, page: pageParam } = await searchParams
  const page = Math.max(1, Number(pageParam) || 1)
  const supabase = await getSupabaseSession()

  // 0 y 1 no dependen entre sí — en paralelo.
  // 0. Surveys para el filtro — dinámico, no hardcodeado. Solo trae lo que
  //    RLS deja ver al usuario autenticado. Si falla, el filtro se degrada a
  //    "sin opciones" en vez de tirar abajo la página entera — la lista de
  //    respuestas no depende de esta query.
  // 1. Preguntas permitidas — text_long e is_sensitive=true se excluyen ACÁ,
  //    antes de tocar la tabla answers. Sus valores nunca se consultan.
  const [
    { data: surveysData, error: surveysError },
    { data: questionsData, error: questionsError },
  ] = await Promise.all([
    supabase.from('surveys').select('id, title').order('title'),
    supabase
      .from('questions')
      .select('id, code, prompt, type, position')
      .eq('is_sensitive', false)
      .neq('type', 'text_long')
      .order('position', { ascending: true }),
  ])

  const surveys = (surveysData ?? []) as SurveyOption[]
  const selectedSurvey = surveys.find((s) => s.id === surveyId)

  if (questionsError) {
    return (
      <div className="admin-page" role="main">
        <h1 className="admin-title">Control de respuestas</h1>
        <p className="admin-error">No fue posible conectarse a la base de datos.</p>
        <pre className="admin-error-detail">{questionsError.message}</pre>
      </div>
    )
  }

  const allowedQuestions = (questionsData ?? []) as AllowedQuestion[]
  const allowedIds = allowedQuestions.map((q) => q.id)
  const questionMap = new Map(allowedQuestions.map((q) => [q.id, q]))

  // 2. Submissions con sus respuestas — answers!inner + .in() filtra el ARRAY
  //    embebido a solo question_id permitidos (consulta, no post-filtro).
  //    Paginado con .range() — page size 50, no LIMIT fijo sin paginación.
  let responsesQuery = supabase
    .from('responses')
    .select(
      `
      id,
      submitted_at,
      qi_zone,
      qi_sector,
      answers!inner ( value, question_id )
    `
    )
    .in('answers.question_id', allowedIds)

  if (surveyId) {
    responsesQuery = responsesQuery.eq('survey_id', surveyId)
  }

  // 3. Contadores totales (independientes de la página actual). submissionsCount
  //    usa el MISMO answers!inner + .in() que responsesQuery — si contara todas
  //    las responses sin ese filtro, una response sin ningún answer permitido
  //    inflaría el total y totalPages quedaría desalineado con lo que .range()
  //    realmente puede devolver (página "fantasma" al final).
  let submissionsCountQuery = supabase
    .from('responses')
    .select('*, answers!inner(question_id)', { count: 'exact', head: true })
    .in('answers.question_id', allowedIds)

  if (surveyId) {
    submissionsCountQuery = submissionsCountQuery.eq('survey_id', surveyId)
  }

  let answersCountQuery = supabase
    .from('answers')
    .select('*, responses!inner(survey_id)', { count: 'exact', head: true })
    .in('question_id', allowedIds)

  if (surveyId) {
    answersCountQuery = answersCountQuery.eq('responses.survey_id', surveyId)
  }

  // Las tres son independientes entre sí — en paralelo.
  const [
    { data: responsesData, error: responsesError },
    { count: totalSubmissions },
    { count: totalAnswers },
  ] =
    allowedIds.length > 0
      ? await Promise.all([
          responsesQuery
            .order('submitted_at', { ascending: false })
            .range((page - 1) * PAGE_SIZE, page * PAGE_SIZE - 1),
          submissionsCountQuery,
          answersCountQuery,
        ])
      : [{ data: [] as ResponseRow[], error: null }, { count: 0 }, { count: 0 }]

  if (responsesError) {
    return (
      <div className="admin-page" role="main">
        <h1 className="admin-title">Control de respuestas</h1>
        <p className="admin-error">No fue posible conectarse a la base de datos.</p>
        <pre className="admin-error-detail">{responsesError.message}</pre>
      </div>
    )
  }

  const responses = (responsesData ?? []) as unknown as ResponseRow[]
  const totalPages = Math.max(1, Math.ceil((totalSubmissions ?? 0) / PAGE_SIZE))

  // 4. Aplanar: una fila por answer, ordenadas por position dentro de cada submission
  const rows: DisplayRow[] = []
  responses.forEach((response, idx) => {
    const answers = response.answers
      .filter((a) => questionMap.has(a.question_id))
      .sort(
        (a, b) =>
          questionMap.get(a.question_id)!.position - questionMap.get(b.question_id)!.position
      )

    answers.forEach((a, ai) => {
      const q = questionMap.get(a.question_id)!
      const isFirstInGroup = ai === 0
      rows.push({
        key: `${response.id}-${a.question_id}`,
        responseId: response.id,
        submissionNum: (page - 1) * PAGE_SIZE + idx + 1,
        isFirstInGroup,
        date: isFirstInGroup ? formatDate(response.submitted_at) : '',
        code: q.code,
        prompt: truncate(q.prompt),
        rendered: renderValue(a.value, q.type),
        zone: isFirstInGroup ? (response.qi_zone ?? '—') : '',
        sector: isFirstInGroup ? (response.qi_sector ?? '—') : '',
      })
    })
  })

  return (
    <div className="admin-page" role="main">
      <header className="admin-header">
        <div>
          <h1 className="admin-title">Control de respuestas</h1>
          <p className="admin-subtitle">
            {totalSubmissions ?? 0} submissions · {totalAnswers ?? 0} respuestas individuales ·{' '}
            {selectedSurvey ? selectedSurvey.title : 'Todos los surveys'} · actualizado{' '}
            {formatDate(new Date().toISOString())}
          </p>
          <p className="admin-subtitle">
            Página {page} de {totalPages} · {totalSubmissions ?? 0} submissions totales
          </p>
          <div className="admin-survey-nav">
            <SurveySelect surveys={surveys} value={surveyId ?? ''} />
          </div>
          {surveysError && (
            <p className="admin-error" role="alert">
              No se pudo cargar la lista de surveys para el filtro — se muestra "Todos".
            </p>
          )}
        </div>
        <div className="admin-header-actions">
          <a href="/admin/responses" className="admin-refresh">Actualizar</a>
          <SignOutButton />
        </div>
      </header>

      <div className="admin-table-wrapper">
        <ResponsesTable rows={rows} surveyId={surveyId} page={page} />
        {rows.length === 0 && (
          <p className="admin-empty">Sin respuestas registradas todavía.</p>
        )}
      </div>

      {(totalSubmissions ?? 0) > PAGE_SIZE && (
        <nav className="admin-pagination" aria-label="Paginación de respuestas">
          {page > 1 ? (
            <a href={pageHref(surveyId, page - 1)} className="admin-pagination-link">← Anterior</a>
          ) : (
            <span className="admin-pagination-link admin-pagination-disabled" aria-disabled="true">← Anterior</span>
          )}
          <span className="admin-pagination-current">Página {page} de {totalPages}</span>
          {page < totalPages ? (
            <a href={pageHref(surveyId, page + 1)} className="admin-pagination-link">Siguiente →</a>
          ) : (
            <span className="admin-pagination-link admin-pagination-disabled" aria-disabled="true">Siguiente →</span>
          )}
        </nav>
      )}
    </div>
  )
}
