import { Link, router } from '@inertiajs/react'
import { CircleDashedIcon, StarIcon, StarOffIcon } from 'lucide-react'

import { DeltaCell } from '@/components/DeltaCell'
import { EmptyState } from '@/components/EmptyState'
import { SectionCard } from '@/components/SectionCard'
import { Button } from '@/components/ui/button'
import { AppLayout } from '@/layouts/AppLayout'
import { formatNumber } from '@/lib/format'
import { t } from '@/lib/i18n'
import { route } from '@/lib/routes'
import { KeywordChart } from '@/pages/Seo/chart'
import { MetricsTable } from '@/pages/Seo/MetricsTable'
import type { KeywordDetail } from '@/pages/Seo/types'

interface Props {
  keyword: KeywordDetail
  window_days: number
  min_impressions: number
}

const WINDOWS = [1, 3, 7, 15] as const

/**
 * La ficha de una consulta: su evolución, su tráfico y qué URLs compiten por ella.
 *
 * Es pantalla y no panel. La regla de abrir una cifra donde se la lee apunta a
 * listas cortas que mandan a otra vista sin contexto; acá el destino sabe de qué
 * consulta se habla y trae análisis propio: cabecera, serie temporal, reparto
 * por página e historial diario. Eso no entra en un panel lateral.
 */
export default function Keyword({ keyword, window_days, min_impressions }: Props) {
  function toggleTracking() {
    router.post(route('seo.keyword.track'), {
      keyword: keyword.query,
      tracked: keyword.tracked ? 'false' : 'true',
      origin: 'detail',
    })
  }

  return (
    <AppLayout
      title={keyword.query}
      description={t('seo.keyword.description', { days: window_days })}
      actions={
        <Button variant={keyword.tracked ? 'outline' : 'default'} onClick={toggleTracking}>
          {keyword.tracked ? <StarOffIcon aria-hidden /> : <StarIcon aria-hidden />}
          {keyword.tracked ? t('seo.keyword.untrack') : t('seo.keyword.track')}
        </Button>
      }
    >
      {!keyword.has_data ? (
        <SectionCard title={{ text: t('seo.keyword.noData.title') }}>
          <EmptyState
            icon={CircleDashedIcon}
            title={t('seo.keyword.noData.title')}
            description={t('seo.keyword.noData.description')}
            className="border-0"
          />
        </SectionCard>
      ) : (
        <>
          <SectionCard
            title={{ text: t('seo.keyword.summary') }}
            description={t('seo.keyword.summaryHelp', { days: window_days })}
          >
            <dl className="grid gap-4 sm:grid-cols-4">
              <Figure label={t('seo.column.position')} value={keyword.position.toFixed(1)} />
              <Figure
                label={t('seo.column.impressions')}
                value={formatNumber(keyword.impressions)}
              />
              <Figure label={t('seo.column.clicks')} value={formatNumber(keyword.clicks)} />
              <Figure
                label={t('seo.column.ctr')}
                value={`${(keyword.ctr * 100).toFixed(1)}%`}
              />
            </dl>

            <div className="flex flex-wrap gap-6 pt-2">
              {WINDOWS.map((days) => (
                <div key={days} className="flex flex-col gap-1">
                  <span className="text-muted-foreground text-xs">
                    {t('seo.column.delta', { days })}
                  </span>
                  <DeltaCell
                    delta={keyword.deltas[String(days)] ?? null}
                    window={days}
                    minImpressions={min_impressions}
                  />
                </div>
              ))}
            </div>
          </SectionCard>

          <SectionCard
            title={{ text: t('seo.keyword.evolution') }}
            description={t('seo.keyword.evolutionHelp')}
          >
            <KeywordChart history={keyword.history} />
          </SectionCard>

          <SectionCard
            title={{ text: t('seo.keyword.pages') }}
            description={t('seo.keyword.pagesHelp')}
          >
            {keyword.pages.length === 0 ? (
              <EmptyState
                icon={CircleDashedIcon}
                title={t('seo.keyword.pages.empty.title')}
                description={t('seo.keyword.pages.empty.description')}
                className="border-0"
              />
            ) : (
              /*
                Con encabezados. Antes eran tres números pegados a la derecha
                —«43 %», «12,4», «318»— y había que deducir por el tamaño de cada
                uno cuál era el reparto, cuál la posición y cuál las impresiones.
              */
              <MetricsTable
                caption={t('seo.keyword.pages')}
                rows={keyword.pages}
                rowKey={(page) => page.page}
                columns={[
                  {
                    header: t('seo.column.page'),
                    cell: (page) => (
                      <Link
                        href={`${route('seo.page')}?url=${encodeURIComponent(page.page)}`}
                        className="hover:underline"
                        translate="no"
                      >
                        {page.page}
                      </Link>
                    ),
                  },
                  {
                    header: t('seo.column.share'),
                    numeric: true,
                    cell: (page) => t('seo.share', { share: (page.share * 100).toFixed(0) }),
                  },
                  {
                    header: t('seo.column.position'),
                    numeric: true,
                    cell: (page) => page.position.toFixed(1),
                  },
                  {
                    header: t('seo.column.impressions'),
                    numeric: true,
                    cell: (page) => formatNumber(page.impressions),
                  },
                  {
                    header: t('seo.column.clicks'),
                    numeric: true,
                    cell: (page) => formatNumber(page.clicks),
                  },
                ]}
              />
            )}
          </SectionCard>
        </>
      )}
    </AppLayout>
  )
}

function Figure({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex flex-col gap-1">
      <dt className="text-muted-foreground text-xs">{label}</dt>
      <dd className="text-2xl font-semibold tabular-nums">{value}</dd>
    </div>
  )
}
