import { redirect } from 'next/navigation'
import { createClient } from '@/lib/supabase/server'
import { getAppOrg } from '@/lib/org'
import { getEffectiveUser } from '@/lib/effective-user'
import { canTransfer } from '@/lib/permissions'
import { blockerReason } from '@/lib/toggl'
import { FilterBar } from '@/components/filter-bar'
import { readFiltersFromSearchParams } from '@/lib/filters'
import { fmtHoursMinutes, fmtHoursMinutesSeconds, fmtTimestampShort, fmtUsd } from '@/lib/format'
import { TransferTable } from './transfer-table'

const SORT_COLUMNS: Record<string, string> = {
  date: 'start_at',
  user: 'converted_user',
  source_email: 'source_user_email',
  project: 'project',
  description: 'description',
  source_hrs: 'duration_seconds',
  billout_hrs: 'converted_duration_seconds',
  cost: 'converted_duration_seconds',
}
import { unmarkBatch } from './actions'
import { DeleteForm } from '@/components/delete-form'

type Entry = {
  id: string
  source_user_email: string | null
  team_member_id: string | null
  operator: string | null
  client: string | null
  project: string | null
  description: string | null
  billable: boolean | null
  start_at: string
  end_at: string | null
  duration_seconds: number | null
  converted_user: string | null
  converted_duration_seconds: number | null
  billout_cost_usd: number | null
}

type Batch = {
  transfer_batch_id: string
  transferred_at: string
  row_count: number
}

export default async function TransferPage({
  searchParams,
}: {
  searchParams: Promise<Record<string, string | string[] | undefined>>
}) {
  const sp = await searchParams
  const error = typeof sp.error === 'string' ? sp.error : null
  const marked = typeof sp.marked === 'string' ? sp.marked : null
  const unmarked = typeof sp.unmarked === 'string'

  const sortKey = typeof sp.sort === 'string' ? sp.sort : 'date'
  const sortDir = (typeof sp.dir === 'string' ? sp.dir : 'asc') as 'asc' | 'desc'
  const sortColumn = SORT_COLUMNS[sortKey] ?? 'start_at'

  const supabase = await createClient()
  const org = await getAppOrg(supabase)

  if (!org) {
    return (
      <main>
        <div className="page-head">
          <h1>Transfer</h1>
        </div>
        <p className="error">Bowden Works organization not found.</p>
      </main>
    )
  }

  const eu = await getEffectiveUser(supabase, org.id)
  const userCanTransfer = canTransfer(eu)
  if (!userCanTransfer) {
    // Adi (manager) and anyone else without transfer rights can't see this page.
    redirect('/')
  }

  // Default "Relevant month" for the export = previous calendar month (YYYY-MM).
  // The invoicing sheet uses this label to bucket entries by billing month.
  // Computed in server tz; the user can override on the form.
  const now = new Date()
  const prevMonthYear =
    now.getMonth() === 0 ? now.getFullYear() - 1 : now.getFullYear()
  const prevMonthNum = now.getMonth() === 0 ? 12 : now.getMonth()
  const defaultRelevantMonth = `${prevMonthYear}-${prevMonthNum
    .toString()
    .padStart(2, '0')}`

  const { startBound, endBound } = readFiltersFromSearchParams(sp)

  // Pending entries, with date filter applied
  let query = supabase
    .from('time_entries')
    .select(
      'id, source_user_email, team_member_id, operator, client, project, description, billable, start_at, end_at, duration_seconds, converted_user, converted_duration_seconds, billout_cost_usd',
    )
    .eq('org_id', org.id)
    .is('transferred_at', null)
    .order(sortColumn, { ascending: sortDir === 'asc', nullsFirst: false })
    .limit(5000)
  if (startBound) query = query.gte('start_at', startBound)
  if (endBound) query = query.lt('start_at', endBound)

  const { data: pending } = await query.returns<Entry[]>()

  const eligible = (pending ?? []).filter((e) => !blockerReason(e))
  const blocked = (pending ?? []).filter((e) => blockerReason(e))

  const eligibleHours = eligible.reduce(
    (acc, e) => acc + (e.converted_duration_seconds ?? 0),
    0,
  )

  // Recent transferred batches
  const { data: rawBatches } = await supabase
    .from('time_entries')
    .select('transfer_batch_id, transferred_at')
    .eq('org_id', org.id)
    .not('transfer_batch_id', 'is', null)
    .order('transferred_at', { ascending: false })
    .limit(2000)
    .returns<{ transfer_batch_id: string; transferred_at: string }[]>()

  const batchMap = new Map<string, Batch>()
  for (const r of rawBatches ?? []) {
    const existing = batchMap.get(r.transfer_batch_id)
    if (existing) {
      existing.row_count += 1
    } else {
      batchMap.set(r.transfer_batch_id, {
        transfer_batch_id: r.transfer_batch_id,
        transferred_at: r.transferred_at,
        row_count: 1,
      })
    }
  }
  const recentBatches = Array.from(batchMap.values())
    .sort((a, b) => b.transferred_at.localeCompare(a.transferred_at))
    .slice(0, 10)

  return (
    <main>
      <div className="page-head">
        <div>
          <h1>Transfer</h1>
          <p className="subtitle">
            Pending entries ready for Toggl. Download the CSV, import in Toggl,
            then come back and mark the rows as transferred only after that
            import succeeded.
          </p>
        </div>
      </div>

      {error && <p className="error">{error}</p>}
      {marked && (
        <p className="info">
          ✓ Marked entries as transferred (batch{' '}
          <code>{marked.slice(0, 8)}</code>). You can undo this below if Toggl
          rejected the import.
        </p>
      )}
      {unmarked && (
        <p className="info">
          ✓ Batch undone — those entries are back in the pending list.
        </p>
      )}

      {blocked.length > 0 && (
        <p className="warning">
          <strong>{blocked.length}</strong> pending{' '}
          {blocked.length === 1 ? 'entry is' : 'entries are'} blocked from
          transfer (usually missing client or unknown source email). They&apos;re
          excluded from any export. See the Blocked table below for the reason
          on each, or fix them on the{' '}
          <a href="/entries?status=blocked">Entries</a> page.
        </p>
      )}

      <FilterBar />

      <div className="panel">
        <div className="stat-row">
          <div className="stat">
            <span className="stat-label">In filter, pending</span>
            <span className="stat-value">{pending?.length ?? 0}</span>
          </div>
          <div className="stat">
            <span className="stat-label">Ready</span>
            <span className="stat-value">{eligible.length}</span>
            <span className="stat-sub">{fmtHoursMinutes(eligibleHours)}</span>
          </div>
          <div className="stat">
            <span className="stat-label">Blocked</span>
            <span
              className={`stat-value ${blocked.length > 0 ? 'under-target' : ''}`}
            >
              {blocked.length}
            </span>
          </div>
        </div>
        {!userCanTransfer && eu?.is_viewing_as && (
          <p
            className="muted"
            style={{ marginTop: '1rem', fontSize: '0.9em' }}
          >
            Viewing as {eu.view_as_label} — they can&apos;t mark entries as
            transferred. Switch out of view-as mode (banner above) to do that.
          </p>
        )}
      </div>

      {blocked.length > 0 && (
        <div className="panel" style={{ padding: 0, overflow: 'hidden' }}>
          <div style={{ padding: '1rem 1.25rem 0.5rem' }}>
            <h2 style={{ margin: 0, fontSize: '1.05rem' }}>
              Blocked ({blocked.length})
            </h2>
            <p
              className="muted"
              style={{ fontSize: '0.85em', margin: '0.25rem 0 0' }}
            >
              These are excluded from the export. Most often the source email
              isn&apos;t in <a href="/team">Team</a> yet — add it, then edit
              the entry on the <a href="/entries">Entries</a> page to re-resolve.
            </p>
          </div>
          <div className="table-wrap" style={{ border: 'none', borderRadius: 0 }}>
            <table className="data">
              <thead>
                <tr>
                  <th>Reason</th>
                  <th>Source email</th>
                  <th>Date</th>
                  <th>Client</th>
                  <th>Project</th>
                  <th>Description</th>
                  <th className="num">Source hrs</th>
                </tr>
              </thead>
              <tbody>
                {blocked.map((e) => (
                  <tr key={e.id} className="row-blocked">
                    <td>
                      <span className="badge badge-danger">
                        {blockerReason(e)}
                      </span>
                    </td>
                    <td>{e.source_user_email ?? '—'}</td>
                    <td>{fmtTimestampShort(e.start_at)}</td>
                    <td>{e.client ?? '—'}</td>
                    <td>{e.project ?? '—'}</td>
                    <td>{e.description ?? '—'}</td>
                    <td className="num">{fmtHoursMinutes(e.duration_seconds)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      <TransferTable
        entries={eligible}
        canTransfer={userCanTransfer}
        defaultRelevantMonth={defaultRelevantMonth}
      />

      {recentBatches.length > 0 && (
        <div className="panel" style={{ padding: 0, overflow: 'hidden' }}>
          <div style={{ padding: '1rem 1.25rem 0.5rem' }}>
            <h2 style={{ margin: 0, fontSize: '1.05rem' }}>
              Recent transfer batches
            </h2>
            <p className="muted" style={{ fontSize: '0.85em', margin: '0.25rem 0 0' }}>
              Re-download a batch, or undo it if Toggl rejected the import.
            </p>
          </div>
          <div className="table-wrap" style={{ border: 'none', borderRadius: 0 }}>
            <table className="data">
              <thead>
                <tr>
                  <th>When</th>
                  <th>Batch</th>
                  <th className="num">Rows</th>
                  <th />
                </tr>
              </thead>
              <tbody>
                {recentBatches.map((b) => (
                  <tr key={b.transfer_batch_id}>
                    <td>{new Date(b.transferred_at).toLocaleString()}</td>
                    <td>
                      <code style={{ fontSize: '0.85em' }}>
                        {b.transfer_batch_id.slice(0, 8)}
                      </code>
                    </td>
                    <td className="num">{b.row_count}</td>
                    <td className="right">
                      <div
                        className="flex-row"
                        style={{
                          justifyContent: 'flex-end',
                          gap: '0.75rem',
                        }}
                      >
                        <a
                          href={`/transfer/download?batch_id=${b.transfer_batch_id}`}
                        >
                          Re-download
                        </a>
                        {userCanTransfer && (
                          <DeleteForm
                            action={unmarkBatch}
                            id={b.transfer_batch_id}
                            label="Undo"
                            confirmText={`Undo this batch of ${b.row_count} entries? They'll go back to pending.`}
                          />
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </main>
  )
}
