'use client'

import { useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/router'
import { blocksApi, Block } from '@/services/api/blocks'
import { Card, Address, Table } from '@/libs/frontend-ui-primitives'
import Link from 'next/link'
import { DetailRow } from '@/components/common/DetailRow'
import CompactMetricBar from '@/components/common/CompactMetricBar'
import PageIntro from '@/components/common/PageIntro'
import SectionTabs, { TabPanel, type SectionTab } from '@/components/common/SectionTabs'
import { formatInteger, formatTimestamp, formatWeiAsEth } from '@/utils/format'
import { type Transaction } from '@/services/api/transactions'
import { useBlockTransactions } from '@/hooks/useBlockTransactions'

export default function BlockDetailPage() {
  const router = useRouter()
  const rawNumber = typeof router.query.number === 'string' ? router.query.number : ''
  const blockNumber = parseInt(rawNumber, 10)
  const isValidBlock = rawNumber !== '' && !Number.isNaN(blockNumber) && blockNumber >= 0
  const chainId = parseInt(process.env.NEXT_PUBLIC_CHAIN_ID || '138')

  const [block, setBlock] = useState<Block | null>(null)
  const [loading, setLoading] = useState(true)
  const [activeTab, setActiveTab] = useState<'summary' | 'transactions'>('summary')

  const {
    transactions: blockTransactions,
    loading: transactionsLoading,
    error: transactionsError,
    hasNextPage: hasNextTransactionsPage,
    page: transactionPage,
    setPage: setTransactionPage,
  } = useBlockTransactions({
    blockNumber,
    chainId,
    enabled: router.isReady && isValidBlock,
  })

  useEffect(() => {
    if (!router.isReady) {
      return
    }
    if (!isValidBlock) {
      setLoading(false)
      setBlock(null)
      return
    }

    let cancelled = false
    setLoading(true)

    void (async () => {
      try {
        const response = await blocksApi.getByNumber(chainId, blockNumber)
        if (cancelled) {
          return
        }
        setBlock(response.data)
      } catch (error) {
        console.error('Failed to load block:', error)
        if (cancelled) {
          return
        }
        setBlock(null)
      } finally {
        if (!cancelled) {
          setLoading(false)
        }
      }
    })()

    return () => {
      cancelled = true
    }
  }, [blockNumber, chainId, isValidBlock, router.isReady])

  const gasUtilization = block && block.gas_limit > 0
    ? Math.round((block.gas_used / block.gas_limit) * 100)
    : null
  const transactionColumns = useMemo(() => [
    {
      header: 'Hash',
      accessor: (transaction: Transaction) => (
        <Link href={`/transactions/${transaction.hash}`} className="text-primary-600 hover:underline">
          <Address address={transaction.hash} truncate showCopy={false} />
        </Link>
      ),
    },
    {
      header: 'From',
      accessor: (transaction: Transaction) => (
        <Link href={`/addresses/${transaction.from_address}`} className="text-primary-600 hover:underline">
          <Address address={transaction.from_address} truncate showCopy={false} />
        </Link>
      ),
    },
    {
      header: 'To',
      accessor: (transaction: Transaction) =>
        transaction.to_address ? (
          <Link href={`/addresses/${transaction.to_address}`} className="text-primary-600 hover:underline">
            <Address address={transaction.to_address} truncate showCopy={false} />
          </Link>
        ) : (
          <span className="text-gray-500 dark:text-gray-400">Contract creation</span>
        ),
    },
    {
      header: 'Value',
      accessor: (transaction: Transaction) => formatWeiAsEth(transaction.value),
    },
    {
      header: 'Status',
      accessor: (transaction: Transaction) => (
        <span className={transaction.status === 1 ? 'text-green-600' : 'text-red-600'}>
          {transaction.status === 1 ? 'Success' : 'Failed'}
        </span>
      ),
    },
  ], [])

  const transactionsEmptyMessage = transactionsError
    ? 'Unable to load indexed block transactions right now. Please retry from this page in a moment.'
    : (block?.transaction_count ?? 0) > 0
    ? 'No indexed block transactions were returned for this page yet.'
    : 'This block does not contain any indexed transactions.'

  const blockIntroActions = useMemo(() => {
    const actions = [
      { href: '/blocks', label: 'All blocks' },
      { href: '/transactions', label: 'Transactions' },
    ]
    if (block && block.number > 0) {
      actions.push({ href: `/blocks/${block.number - 1}`, label: 'Previous' })
    }
    if (block) {
      actions.push({ href: `/blocks/${block.number + 1}`, label: 'Next' })
    }
    return actions
  }, [block])

  const blockTabs = useMemo<SectionTab<'summary' | 'transactions'>[]>(
    () => [
      { id: 'summary', label: 'Summary' },
      { id: 'transactions', label: 'Transactions', count: block?.transaction_count ?? 0 },
    ],
    [block?.transaction_count],
  )

  return (
    <div className="container mx-auto px-4 py-4 sm:py-6">
      <PageIntro
        compact
        eyebrow="Block Detail"
        title={block ? `Block #${block.number}` : 'Block'}
        description="Chain 138 block detail, miner, adjacent blocks, and transactions."
        actions={blockIntroActions}
      />

      {!router.isReady || loading ? (
        <Card>
          <p className="text-sm text-gray-600 dark:text-gray-400">Loading block...</p>
        </Card>
      ) : !isValidBlock ? (
        <Card>
          <p className="text-sm text-gray-600 dark:text-gray-400">Invalid block number. Please use a valid block number from the URL.</p>
          <div className="mt-4 flex flex-wrap gap-3 text-sm">
            <Link href="/blocks" className="text-primary-600 hover:underline">
              Back to blocks →
            </Link>
            <Link href="/search" className="text-primary-600 hover:underline">
              Search by block number →
            </Link>
          </div>
        </Card>
      ) : !block ? (
        <Card>
          <p className="text-sm text-gray-600 dark:text-gray-400">Block not found.</p>
          <div className="mt-4 flex flex-wrap gap-3 text-sm">
            <Link href="/blocks" className="text-primary-600 hover:underline">
              Browse recent blocks →
            </Link>
            <Link href="/search" className="text-primary-600 hover:underline">
              Search the explorer →
            </Link>
          </div>
        </Card>
      ) : (
        <>
          <CompactMetricBar
            metrics={[
              { label: 'Transactions', value: formatInteger(block.transaction_count) },
              { label: 'Gas used', value: `${gasUtilization ?? 0}%` },
              { label: 'Gas limit', value: formatInteger(block.gas_limit) },
              { label: 'Miner', value: `${block.miner.slice(0, 6)}…${block.miner.slice(-4)}` },
            ]}
          />

          <SectionTabs
            tabs={blockTabs}
            activeTab={activeTab}
            onChange={setActiveTab}
            idPrefix="block-detail"
            ariaLabel="Block detail sections"
            className="-mx-4 mb-4 px-4"
          />

          <TabPanel idPrefix="block-detail" tabId="summary" activeTab={activeTab}>
        <Card title="Block Information">
          <dl className="space-y-4">
            <DetailRow label="Hash">
              <Address address={block.hash} />
            </DetailRow>
            <DetailRow label="Timestamp">
              {formatTimestamp(block.timestamp)}
            </DetailRow>
            <DetailRow label="Miner">
              <Link href={`/addresses/${block.miner}`} className="text-primary-600 hover:underline">
                <Address address={block.miner} truncate showCopy={false} />
              </Link>
            </DetailRow>
            <DetailRow label="Transactions">
              <button
                type="button"
                onClick={() => setActiveTab('transactions')}
                className="text-primary-600 hover:underline"
              >
                {block.transaction_count}
              </button>
            </DetailRow>
            <DetailRow label="Gas Used">
              {formatInteger(block.gas_used)} / {formatInteger(block.gas_limit)}
            </DetailRow>
            {gasUtilization != null && (
              <DetailRow label="Gas Utilization">
                {gasUtilization}%
              </DetailRow>
            )}
          </dl>
        </Card>
          </TabPanel>

          <TabPanel idPrefix="block-detail" tabId="transactions" activeTab={activeTab}>
        <Card title="Block Transactions">
          <div id="block-transactions" className="space-y-4">
            <p className="text-sm text-gray-600 dark:text-gray-400">
              Indexed transaction set for block #{formatInteger(block.number)}.
            </p>
            {transactionsLoading ? (
              <p className="text-sm text-gray-600 dark:text-gray-400">Loading block transactions...</p>
            ) : (
              <>
                <Table
                  columns={transactionColumns}
                  data={blockTransactions}
                  emptyMessage={transactionsEmptyMessage}
                  keyExtractor={(transaction) => transaction.hash}
                />
                {block.transaction_count > 0 ? (
                  <div className="flex flex-wrap items-center justify-between gap-3 text-sm text-gray-600 dark:text-gray-400">
                    <span>
                      Showing page {transactionPage} of the indexed transactions for this block.
                    </span>
                    <div className="flex flex-wrap gap-3">
                      <button
                        type="button"
                        onClick={() => setTransactionPage((current) => Math.max(1, current - 1))}
                        disabled={transactionsLoading || transactionPage === 1}
                        className="rounded bg-gray-200 px-4 py-2 text-gray-900 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-gray-100"
                      >
                        Previous tx page
                      </button>
                      <button
                        type="button"
                        onClick={() => setTransactionPage((current) => current + 1)}
                        disabled={transactionsLoading || !hasNextTransactionsPage}
                        className="rounded bg-gray-200 px-4 py-2 text-gray-900 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-800 dark:text-gray-100"
                      >
                        Next tx page
                      </button>
                    </div>
                  </div>
                ) : null}
              </>
            )}
          </div>
        </Card>
          </TabPanel>
        </>
      )}
    </div>
  )
}
