import { notFound, redirect } from 'next/navigation'
import { eq, and, desc } from 'drizzle-orm'
import { auth } from '@/auth'
import { db } from '@/db'
import { tickets, ticketMessages, aiArtifacts, projects, users } from '@/db/schema'
import { transition } from '@/lib/ticket-state-machine'
import { loadTenantConfig } from '@/lib/tenant-config-loader'
import { normalizeSupportedLanguage } from '@/lib/user-language'
import { applyAiArtifactTranslation, applyTicketMessageTranslations, applyTicketTranslation } from '@/lib/content-translation-display'
import { getConfigOptionLabel } from '@/lib/config-option-labels'
import { canAnswerClarificationQuestions, canSeeClarificationWaitingState } from '@/lib/ticket-detail-actions'
import { groupTicketMessages } from '@/lib/ticket-message-display'
import { getDraftButtonLabelKey, getDraftUiState } from '@/lib/ticket-draft-ui'
import { getI18nForUserId } from '@/lib/i18n/server'
import { I18nProvider } from '@/lib/i18n/client'
import path from 'path'
import ClarificationForm from './ClarificationForm'
import CloseTicketButton from './CloseTicketButton'
import FollowUpForm from './FollowUpForm'
import TagEditor from './TagEditor'
import ExpertReplyForm from './ExpertReplyForm'
import {
  AiSummaryPanel,
  ClarificationWaitingPanel,
  DraftGeneratingState,
  DraftRequestPanel,
  DraftResponseSection,
  ExpertManualResponseSection,
  MessageThread,
  SubmissionDetailsPanel,
  TicketHeader,
} from './TicketDetailSections'

const CONFIG_PATH = path.resolve(process.cwd(), 'tenant.config.yaml')

const ACTIVE_EXPERT_RESPONSE_STATUSES = [
  'SUBMITTED',
  'NEEDS_INFO',
  'TRIAGED',
  'AWAITING_EXPERT',
  'EXPERT_REVIEWING',
  'RESPONSE_DRAFTING',
  'RESPONSE_READY',
  'AWAITING_REPLY',
  'RESPONDED',
]

export default async function TicketPage({
  params,
}: {
  params: Promise<{ ticketId: string }>
}) {
  const session = await auth()
  if (!session?.user?.id) redirect('/login')
  const i18n = await getI18nForUserId(session.user.id)
  const t = i18n.t
  const statusLabels: Record<string, string> = {
    DRAFT: t('ticket.status.DRAFT'),
    SUBMITTED: t('ticket.status.SUBMITTED'),
    NEEDS_INFO: t('ticket.status.NEEDS_INFO'),
    TRIAGED: t('ticket.status.TRIAGED'),
    AWAITING_EXPERT: t('ticket.status.AWAITING_EXPERT'),
    EXPERT_REVIEWING: t('ticket.status.EXPERT_REVIEWING'),
    RESPONSE_DRAFTING: t('ticket.status.RESPONSE_DRAFTING'),
    RESPONSE_READY: t('ticket.status.RESPONSE_READY'),
    RESPONDED: t('ticket.status.RESPONDED'),
    AWAITING_REPLY: t('ticket.status.AWAITING_REPLY'),
    CLOSED: t('ticket.status.CLOSED'),
    ARCHIVED: t('ticket.status.ARCHIVED'),
  }

  const { ticketId } = await params

  const tenantId = session.user.tenantId
  const role = session.user.role
  if (!tenantId) redirect('/login')

  const [ticket] = await db
    .select()
    .from(tickets)
    .where(and(eq(tickets.id, ticketId), eq(tickets.tenantId, tenantId)))
    .limit(1)

  const canViewTicket =
    ticket && (ticket.submitterId === session.user.id || ['expert', 'admin'].includes(role ?? ''))

  if (!canViewTicket) notFound()

  const isExpert = ['expert', 'admin'].includes(role ?? '')
  let visibleTicket = ticket

  if (isExpert && ticket.status === 'AWAITING_EXPERT') {
    const nextStatus = transition(ticket.status, 'EXPERT_REVIEWING')
    const [updatedTicket] = await db
      .update(tickets)
      .set({
        status: nextStatus,
        assignedExpertId: session.user.id,
        version: ticket.version + 1,
        updatedAt: new Date(),
      })
      .where(and(eq(tickets.id, ticket.id), eq(tickets.version, ticket.version)))
      .returning()

    visibleTicket = updatedTicket ?? ticket
  }

  visibleTicket = await applyTicketTranslation(visibleTicket, i18n.language)

  // Fetch submitter's preferred language so ExpertResponseForm can trigger translation preview
  const [submitterRow] = await db
    .select({ preferredLanguage: users.preferredLanguage })
    .from(users)
    .where(eq(users.id, visibleTicket.submitterId))
    .limit(1)
  const submitterLanguage = normalizeSupportedLanguage(submitterRow?.preferredLanguage)

  const messages = await db
    .select({
      id: ticketMessages.id,
      role: ticketMessages.role,
      language: ticketMessages.language,
      bodyRaw: ticketMessages.bodyRaw,
      bodySanitized: ticketMessages.bodySanitized,
      createdAt: ticketMessages.createdAt,
      authorName: users.displayName,
      authorEmail: users.email,
    })
    .from(ticketMessages)
    .leftJoin(users, eq(ticketMessages.authorId, users.id))
    .where(eq(ticketMessages.ticketId, ticketId))
    .orderBy(ticketMessages.createdAt)

  // Fetch the latest clarification_questions artifact if NEEDS_INFO
  const [clarificationArtifact] =
    visibleTicket.status === 'NEEDS_INFO'
      ? await db
          .select()
          .from(aiArtifacts)
          .where(
            and(
              eq(aiArtifacts.ticketId, ticketId),
              eq(aiArtifacts.artifactType, 'clarification_questions'),
            ),
          )
          .orderBy(desc(aiArtifacts.createdAt))
          .limit(1)
      : []

  const questions: string[] = clarificationArtifact?.contentJson
    ? JSON.parse(clarificationArtifact.contentJson).questions ?? []
    : []

  const [summaryArtifact] = await db
    .select()
    .from(aiArtifacts)
    .where(and(eq(aiArtifacts.ticketId, ticketId), eq(aiArtifacts.artifactType, 'summary')))
    .orderBy(desc(aiArtifacts.createdAt))
    .limit(1)
  const localizedSummaryArtifact = await applyAiArtifactTranslation(summaryArtifact ?? null, i18n.language)

  const [draftArtifact] = await db
    .select()
    .from(aiArtifacts)
    .where(and(eq(aiArtifacts.ticketId, ticketId), eq(aiArtifacts.artifactType, 'suggested_response')))
    .orderBy(desc(aiArtifacts.createdAt))
    .limit(1)
  const localizedDraftArtifact = await applyAiArtifactTranslation(draftArtifact ?? null, i18n.language)

  const draftJson = draftArtifact?.contentJson
    ? JSON.parse(draftArtifact.contentJson) as {
        sources?: Array<{ index: number; title: string; slug: string; score?: number }>
        knowledge_gaps?: string[]
      }
    : null
  const draftUiState = getDraftUiState({
    isExpert,
    status: visibleTicket.status,
    hasDraft: Boolean(draftArtifact),
  })
  const draftButtonLabel = getDraftButtonLabelKey(visibleTicket.aiProcessingState) === 'retryDraft'
    ? t('ticketDetail.draftButton.retryDraft')
    : t('ticketDetail.draftButton.generate')
  const hasClarificationQuestions = questions.length > 0
  const showClarificationForm = canAnswerClarificationQuestions({
    isExpert,
    status: visibleTicket.status,
    currentUserId: session.user.id,
    submitterId: visibleTicket.submitterId,
    hasQuestions: hasClarificationQuestions,
  })
  const showClarificationWaitingState = canSeeClarificationWaitingState({
    isExpert,
    status: visibleTicket.status,
    hasQuestions: hasClarificationQuestions,
  })
  const canExpertReply = isExpert && ACTIVE_EXPERT_RESPONSE_STATUSES.includes(visibleTicket.status)
  const lastNonSystemMessage = [...messages].reverse().find(m => m.role !== 'system')
  const showExpertFollowUpReply = canExpertReply && Boolean(visibleTicket.resolutionSeverity) && lastNonSystemMessage?.role === 'line_manager'
  const showExpertManualResponse =
    canExpertReply && !visibleTicket.resolutionSeverity && !draftArtifact && draftUiState !== 'generating'
  const localizedMessages = await applyTicketMessageTranslations(messages, i18n.language)
  const messageGroups = groupTicketMessages(localizedMessages)

  // Load project name for the submission details panel
  let projectName: string | null = null
  if (visibleTicket.projectId) {
    const [project] = await db
      .select({ name: projects.name })
      .from(projects)
      .where(eq(projects.id, visibleTicket.projectId))
      .limit(1)
    projectName = project?.name ?? null
  }

  // Load S-field options from tenant config
  const tenantConfig = await loadTenantConfig(CONFIG_PATH)
  const severityOptions = tenantConfig.intake.resolution_severity_levels
  const concernOptions = tenantConfig.intake.resolution_concern_types

  return (
    <I18nProvider language={i18n.language} dictionary={i18n.dictionary}>
    <main className="min-h-screen bg-zinc-50 px-4 py-12 text-zinc-950 dark:bg-zinc-950 dark:text-zinc-100">
      <div className="max-w-2xl mx-auto space-y-6">
        <TicketHeader
          referenceNumber={visibleTicket.referenceNumber}
          title={visibleTicket.title}
          fallbackTitle={t('ticketDetail.issueSubmitted')}
          statusLabel={statusLabels[visibleTicket.status] ?? visibleTicket.status}
          degradedAiLabel={t('ticketDetail.degradedAi')}
          showDegradedAi={visibleTicket.aiProcessingState === 'degraded'}
        />

        {isExpert && localizedSummaryArtifact ? (
          <AiSummaryPanel title={t('ticketDetail.aiSummary')} content={localizedSummaryArtifact.content} />
        ) : null}

        <SubmissionDetailsPanel
          items={[
            { label: t('ticketDetail.project'), value: projectName },
            { label: t('ticketDetail.dateOfOccurrence'), value: visibleTicket.dateOfOccurrence },
            { label: t('ticketDetail.department'), value: visibleTicket.department ? getConfigOptionLabel(visibleTicket.department, i18n.language) : null },
            { label: t('ticketDetail.issueCategory'), value: visibleTicket.issueCategory ? getConfigOptionLabel(visibleTicket.issueCategory, i18n.language) : null },
            { label: t('ticketDetail.affectedSystem'), value: visibleTicket.affectedSystem ? getConfigOptionLabel(visibleTicket.affectedSystem, i18n.language) : null },
            { label: t('ticketDetail.declaredPriority'), value: visibleTicket.userPriority, capitalize: true },
            { label: t('ticketDetail.actionRequested'), value: visibleTicket.actionRequested ? getConfigOptionLabel(visibleTicket.actionRequested, i18n.language) : null },
            { label: t('ticketDetail.successCriteria'), value: visibleTicket.successCriteria, wide: true },
          ]}
        />

        <MessageThread groups={messageGroups} />

        {/* NEEDS_INFO clarification form — only the submitter answers these questions. */}
        {showClarificationForm && (
          <ClarificationForm ticketId={ticketId} questions={questions} />
        )}

        {showClarificationWaitingState && (
          <ClarificationWaitingPanel
            title={t('ticketDetail.waitingForLineManager')}
            body={t('ticketDetail.waitingForLineManagerBody')}
            questions={questions}
          />
        )}

        {showExpertManualResponse ? (
          <ExpertManualResponseSection
            title={t('ticketDetail.expertOverrideResponse')}
            body={t('ticketDetail.expertOverrideBody')}
            ticketId={ticketId}
            severityOptions={severityOptions}
            concernOptions={concernOptions}
            submitterLanguage={submitterLanguage}
          />
        ) : null}

        {/* RESPONDED — line manager can follow up with the expert */}
        {!isExpert && visibleTicket.status === 'RESPONDED' && (
          <FollowUpForm ticketId={ticketId} context="follow_up" />
        )}

        {/* AWAITING_REPLY — line manager clarification or follow-up */}
        {!isExpert && visibleTicket.status === 'AWAITING_REPLY' && (
          <FollowUpForm
            ticketId={ticketId}
            context={visibleTicket.resolutionSeverity ? 'follow_up' : 'awaiting_reply'}
          />
        )}

        {/* Experts can send follow-up replies after an initial response has been recorded. */}
        {showExpertFollowUpReply && (
          <ExpertReplyForm ticketId={ticketId} />
        )}

        {/* Experts can request a draft once they are reviewing the ticket. */}
        {draftUiState === 'requestable' ? (
          <DraftRequestPanel
            title={t('ticketDetail.responseDraft')}
            body={t('ticketDetail.responseDraftBody')}
            ticketId={ticketId}
            buttonLabel={draftButtonLabel}
          />
        ) : null}

        {/* Auto-poll only while a draft job has actually been queued. */}
        {draftUiState === 'generating' ? (
          <DraftGeneratingState label={t('ticketDetail.generatingDraft')} />
        ) : null}

        {/* Draft form — shown when a draft exists and the expert has not yet responded */}
        {isExpert && draftArtifact && !visibleTicket.resolutionSeverity ? (
          <DraftResponseSection
            ticketId={ticketId}
            draft={localizedDraftArtifact?.content ?? draftArtifact.content}
            sources={draftJson?.sources}
            knowledgeGaps={draftJson?.knowledge_gaps}
            labels={{
              kbSources: t('ticketDetail.kbSources'),
              regenerateDraft: t('ticketDetail.regenerateDraft'),
              noKbSources: t('ticketDetail.noKbSources'),
              knowledgeGaps: t('ticketDetail.knowledgeGaps'),
            }}
            severityOptions={severityOptions}
            concernOptions={concernOptions}
            submitterLanguage={submitterLanguage}
          />
        ) : null}

        {isExpert ? (
          <TagEditor ticketId={ticketId} initialTags={visibleTicket.categoryTags ?? []} />
        ) : null}

        {isExpert && ['RESPONDED', 'AWAITING_REPLY'].includes(visibleTicket.status) ? (
          <div className="flex justify-end">
            <CloseTicketButton ticketId={ticketId} version={visibleTicket.version} />
          </div>
        ) : null}
      </div>
    </main>
    </I18nProvider>
  )
}
