import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { apiClient } from '../../core/api/api-client'

// ─────────────────────────── data fetching ───────────────────────────

const fetchGroups = async () => {
  const res = await apiClient.get('/internal/payment-groups')
  return res.data.data.groups
}

const fetchMethods = async () => {
  const res = await apiClient.get('/internal/payment-methods')
  return res.data.data.methods
}

const errorMessage = (err) => {
  const code = err?.response?.data?.error?.code
  const msg = err?.response?.data?.error?.message
  if (code === 'CONFLICT') return msg || 'Konflik data.'
  if (code === 'VALIDATION') return msg || 'Input tidak valid.'
  if (code === 'NOT_FOUND') return msg || 'Data tidak ditemukan.'
  return msg || 'Gagal menyimpan.'
}

// ─────────────────────────── page ───────────────────────────

export default function PaymentCatalogPage() {
  const qc = useQueryClient()
  const groupsQ = useQuery({ queryKey: ['payment-groups'], queryFn: fetchGroups })
  const methodsQ = useQuery({ queryKey: ['payment-methods'], queryFn: fetchMethods })

  const [selectedGroupId, setSelectedGroupId] = useState(null)
  const [groupForm, setGroupForm] = useState(null) // null | {id?, name, display_order, is_active}
  const [methodForm, setMethodForm] = useState(null)
  const [error, setError] = useState(null)

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['payment-groups'] })
    qc.invalidateQueries({ queryKey: ['payment-methods'] })
  }

  // ─────────────── mutations ───────────────

  const groupCreate = useMutation({
    mutationFn: (body) => apiClient.post('/internal/payment-groups', body),
    onSuccess: () => { invalidate(); setGroupForm(null); setError(null) },
    onError: (e) => setError(errorMessage(e)),
  })
  const groupUpdate = useMutation({
    mutationFn: ({ id, body }) => apiClient.patch(`/internal/payment-groups/${id}`, body),
    onSuccess: () => { invalidate(); setGroupForm(null); setError(null) },
    onError: (e) => setError(errorMessage(e)),
  })
  const groupDelete = useMutation({
    mutationFn: (id) => apiClient.delete(`/internal/payment-groups/${id}`),
    onSuccess: () => { invalidate(); setError(null) },
    onError: (e) => setError(errorMessage(e)),
  })
  const groupsReorder = useMutation({
    mutationFn: (orderedIds) => apiClient.post('/internal/payment-groups/reorder', { ordered_ids: orderedIds }),
    onSuccess: invalidate,
    onError: (e) => setError(errorMessage(e)),
  })

  const methodCreate = useMutation({
    mutationFn: (body) => apiClient.post('/internal/payment-methods', body),
    onSuccess: () => { invalidate(); setMethodForm(null); setError(null) },
    onError: (e) => setError(errorMessage(e)),
  })
  const methodUpdate = useMutation({
    mutationFn: ({ id, body }) => apiClient.patch(`/internal/payment-methods/${id}`, body),
    onSuccess: () => { invalidate(); setMethodForm(null); setError(null) },
    onError: (e) => setError(errorMessage(e)),
  })
  const methodDelete = useMutation({
    mutationFn: (id) => apiClient.delete(`/internal/payment-methods/${id}`),
    onSuccess: () => { invalidate(); setError(null) },
    onError: (e) => setError(errorMessage(e)),
  })
  const methodsReorder = useMutation({
    mutationFn: (orderedIds) => apiClient.post('/internal/payment-methods/reorder', { ordered_ids: orderedIds }),
    onSuccess: invalidate,
    onError: (e) => setError(errorMessage(e)),
  })

  // ─────────────── helpers ───────────────

  const moveGroup = (id, delta) => {
    const ordered = (groupsQ.data ?? []).map((g) => g.id)
    const idx = ordered.indexOf(id)
    const newIdx = idx + delta
    if (idx < 0 || newIdx < 0 || newIdx >= ordered.length) return
    ;[ordered[idx], ordered[newIdx]] = [ordered[newIdx], ordered[idx]]
    groupsReorder.mutate(ordered)
  }

  const moveMethod = (id, delta, groupId) => {
    const inGroup = (methodsQ.data ?? [])
      .filter((m) => m.group_id === groupId)
      .map((m) => m.id)
    const idx = inGroup.indexOf(id)
    const newIdx = idx + delta
    if (idx < 0 || newIdx < 0 || newIdx >= inGroup.length) return
    ;[inGroup[idx], inGroup[newIdx]] = [inGroup[newIdx], inGroup[idx]]
    methodsReorder.mutate(inGroup)
  }

  if (groupsQ.isLoading || methodsQ.isLoading) return <div>Loading…</div>
  if (groupsQ.error || methodsQ.error) return <div>Failed to load payment catalog.</div>

  const groups = groupsQ.data ?? []
  const methods = methodsQ.data ?? []
  const filteredMethods = selectedGroupId
    ? methods.filter((m) => m.group_id === selectedGroupId)
    : methods

  return (
    <div style={{ padding: 24 }}>
      <h1 style={{ marginBottom: 8 }}>Payment Catalog</h1>
      <p style={{ color: '#666', marginBottom: 24, fontSize: 14 }}>
        Groups and methods rendered by the customer app on the "cara bayar"
        screen. Reorder controls the visible order. <code>payment_code</code> must
        match the Xendit channel code exactly (uppercase, e.g. <code>OVO</code>,
        <code>BCA_VA</code>).
      </p>

      {error && (
        <div style={{
          background: '#FFE6E6',
          border: '1px solid #D86B6B',
          color: '#8B2D2D',
          padding: 12,
          borderRadius: 8,
          marginBottom: 16,
        }}>
          {error}
        </div>
      )}

      {/* ───────────── groups ───────────── */}
      <section style={{ marginBottom: 32 }}>
        <header style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
          <h2 style={{ margin: 0 }}>Groups</h2>
          <button
            onClick={() => setGroupForm({ name: '', display_order: groups.length, is_active: true })}
            style={btnStyle('primary')}
          >+ Add group</button>
        </header>
        <table style={tableStyle}>
          <thead>
            <tr>
              <th style={thStyle}>Order</th>
              <th style={thStyle}>Name</th>
              <th style={thStyle}>Active</th>
              <th style={thStyle}>Methods</th>
              <th style={thStyle}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {groups.map((g, i) => {
              const methodsInGroup = methods.filter((m) => m.group_id === g.id).length
              return (
                <tr key={g.id} style={selectedGroupId === g.id ? { background: '#FBEFF3' } : undefined}>
                  <td style={tdStyle}>
                    <div style={{ display: 'flex', gap: 4 }}>
                      <button disabled={i === 0} onClick={() => moveGroup(g.id, -1)} style={btnStyle('ghost')}>↑</button>
                      <button disabled={i === groups.length - 1} onClick={() => moveGroup(g.id, +1)} style={btnStyle('ghost')}>↓</button>
                      <span style={{ marginLeft: 8, color: '#666' }}>{g.display_order}</span>
                    </div>
                  </td>
                  <td style={tdStyle}><strong>{g.name}</strong></td>
                  <td style={tdStyle}>{g.is_active ? '✓' : '✗'}</td>
                  <td style={tdStyle}>{methodsInGroup}</td>
                  <td style={tdStyle}>
                    <button onClick={() => setSelectedGroupId(g.id === selectedGroupId ? null : g.id)} style={btnStyle('ghost')}>
                      {selectedGroupId === g.id ? 'Hide methods' : 'Show methods'}
                    </button>
                    <button onClick={() => setGroupForm(g)} style={btnStyle('ghost')}>Edit</button>
                    <button
                      onClick={() => {
                        if (!confirm(`Delete group "${g.name}"?`)) return
                        groupDelete.mutate(g.id)
                      }}
                      style={btnStyle('danger')}
                      disabled={methodsInGroup > 0}
                      title={methodsInGroup > 0 ? 'Move methods out first' : ''}
                    >Delete</button>
                  </td>
                </tr>
              )
            })}
            {groups.length === 0 && (
              <tr><td colSpan={5} style={{ ...tdStyle, color: '#999' }}>No groups yet.</td></tr>
            )}
          </tbody>
        </table>
      </section>

      {/* ───────────── methods ───────────── */}
      <section>
        <header style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 12 }}>
          <h2 style={{ margin: 0 }}>
            Methods{selectedGroupId && groups.find(g => g.id === selectedGroupId)
              ? ` — ${groups.find(g => g.id === selectedGroupId).name}`
              : ''}
          </h2>
          <button
            disabled={groups.length === 0}
            onClick={() => setMethodForm({
              group_id: selectedGroupId ?? groups[0]?.id,
              display_name: '',
              payment_code: '',
              icon: '',
              display_order: filteredMethods.length,
              is_active: true,
            })}
            style={btnStyle('primary')}
          >+ Add method</button>
        </header>
        <table style={tableStyle}>
          <thead>
            <tr>
              <th style={thStyle}>Order</th>
              <th style={thStyle}>Group</th>
              <th style={thStyle}>Display name</th>
              <th style={thStyle}>Code</th>
              <th style={thStyle}>Icon slug</th>
              <th style={thStyle}>Active</th>
              <th style={thStyle}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {filteredMethods.map((m, i, arr) => (
              <tr key={m.id}>
                <td style={tdStyle}>
                  <div style={{ display: 'flex', gap: 4 }}>
                    <button disabled={i === 0} onClick={() => moveMethod(m.id, -1, m.group_id)} style={btnStyle('ghost')}>↑</button>
                    <button disabled={i === arr.length - 1} onClick={() => moveMethod(m.id, +1, m.group_id)} style={btnStyle('ghost')}>↓</button>
                    <span style={{ marginLeft: 8, color: '#666' }}>{m.display_order}</span>
                  </div>
                </td>
                <td style={tdStyle}>{groups.find((g) => g.id === m.group_id)?.name ?? '—'}</td>
                <td style={tdStyle}><strong>{m.display_name}</strong></td>
                <td style={tdStyle}><code>{m.payment_code}</code></td>
                <td style={tdStyle}>{m.icon || <span style={{ color: '#999' }}>—</span>}</td>
                <td style={tdStyle}>{m.is_active ? '✓' : '✗'}</td>
                <td style={tdStyle}>
                  <button onClick={() => setMethodForm(m)} style={btnStyle('ghost')}>Edit</button>
                  <button
                    onClick={() => {
                      if (!confirm(`Delete "${m.display_name}"?`)) return
                      methodDelete.mutate(m.id)
                    }}
                    style={btnStyle('danger')}
                  >Delete</button>
                </td>
              </tr>
            ))}
            {filteredMethods.length === 0 && (
              <tr><td colSpan={7} style={{ ...tdStyle, color: '#999' }}>
                {selectedGroupId ? 'No methods in this group yet.' : 'No methods yet.'}
              </td></tr>
            )}
          </tbody>
        </table>
      </section>

      {/* ───────────── modals ───────────── */}
      {groupForm && (
        <GroupModal
          form={groupForm}
          onChange={setGroupForm}
          onClose={() => { setGroupForm(null); setError(null) }}
          onSubmit={() => {
            const body = {
              name: groupForm.name?.trim(),
              display_order: Number(groupForm.display_order) || 0,
              is_active: !!groupForm.is_active,
            }
            if (groupForm.id) {
              groupUpdate.mutate({ id: groupForm.id, body })
            } else {
              groupCreate.mutate(body)
            }
          }}
        />
      )}

      {methodForm && (
        <MethodModal
          form={methodForm}
          groups={groups}
          onChange={setMethodForm}
          onClose={() => { setMethodForm(null); setError(null) }}
          onSubmit={() => {
            const body = {
              group_id: methodForm.group_id,
              display_name: methodForm.display_name?.trim(),
              payment_code: methodForm.payment_code?.trim()?.toUpperCase(),
              display_order: Number(methodForm.display_order) || 0,
              icon: methodForm.icon?.trim() || null,
              is_active: !!methodForm.is_active,
            }
            if (methodForm.id) {
              methodUpdate.mutate({ id: methodForm.id, body })
            } else {
              methodCreate.mutate(body)
            }
          }}
        />
      )}
    </div>
  )
}

// ─────────────────────────── modals ───────────────────────────

const GroupModal = ({ form, onChange, onSubmit, onClose }) => (
  <Modal title={form.id ? 'Edit group' : 'New group'} onClose={onClose}>
    <Field label="Name">
      <input
        value={form.name ?? ''}
        onChange={(e) => onChange({ ...form, name: e.target.value })}
        style={inputStyle}
      />
    </Field>
    <Field label="Display order">
      <input
        type="number"
        value={form.display_order ?? 0}
        onChange={(e) => onChange({ ...form, display_order: e.target.value })}
        style={inputStyle}
      />
    </Field>
    <Field label="Active">
      <input
        type="checkbox"
        checked={!!form.is_active}
        onChange={(e) => onChange({ ...form, is_active: e.target.checked })}
      />
    </Field>
    <Footer onClose={onClose} onSubmit={onSubmit} />
  </Modal>
)

const MethodModal = ({ form, groups, onChange, onSubmit, onClose }) => (
  <Modal title={form.id ? 'Edit method' : 'New method'} onClose={onClose}>
    <Field label="Group">
      <select
        value={form.group_id ?? ''}
        onChange={(e) => onChange({ ...form, group_id: e.target.value })}
        style={inputStyle}
      >
        {groups.map((g) => <option key={g.id} value={g.id}>{g.name}</option>)}
      </select>
    </Field>
    <Field label="Display name">
      <input
        value={form.display_name ?? ''}
        onChange={(e) => onChange({ ...form, display_name: e.target.value })}
        style={inputStyle}
      />
    </Field>
    <Field label="Payment code (Xendit channel)">
      <input
        value={form.payment_code ?? ''}
        onChange={(e) => onChange({ ...form, payment_code: e.target.value })}
        placeholder="OVO, DANA, QRIS, BCA_VA, …"
        style={inputStyle}
      />
    </Field>
    <Field label="Icon slug (file in client_app/assets/payment_icons/)">
      <input
        value={form.icon ?? ''}
        onChange={(e) => onChange({ ...form, icon: e.target.value })}
        placeholder="ovo, dana, qris, …"
        style={inputStyle}
      />
    </Field>
    <Field label="Display order">
      <input
        type="number"
        value={form.display_order ?? 0}
        onChange={(e) => onChange({ ...form, display_order: e.target.value })}
        style={inputStyle}
      />
    </Field>
    <Field label="Active">
      <input
        type="checkbox"
        checked={!!form.is_active}
        onChange={(e) => onChange({ ...form, is_active: e.target.checked })}
      />
    </Field>
    <Footer onClose={onClose} onSubmit={onSubmit} />
  </Modal>
)

const Modal = ({ title, onClose, children }) => (
  <div style={{
    position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)',
    display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 100,
  }} onClick={onClose}>
    <div
      style={{ background: 'white', padding: 24, borderRadius: 12, minWidth: 420, maxWidth: 560 }}
      onClick={(e) => e.stopPropagation()}
    >
      <h3 style={{ marginTop: 0 }}>{title}</h3>
      {children}
    </div>
  </div>
)

const Field = ({ label, children }) => (
  <div style={{ marginBottom: 12, display: 'flex', flexDirection: 'column' }}>
    <label style={{ fontSize: 12, fontWeight: 600, color: '#444', marginBottom: 4 }}>{label}</label>
    {children}
  </div>
)

const Footer = ({ onClose, onSubmit }) => (
  <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16 }}>
    <button onClick={onClose} style={btnStyle('ghost')}>Cancel</button>
    <button onClick={onSubmit} style={btnStyle('primary')}>Save</button>
  </div>
)

// ─────────────────────────── inline styles ───────────────────────────

const tableStyle = { width: '100%', borderCollapse: 'collapse', background: 'white', borderRadius: 8, overflow: 'hidden', boxShadow: '0 1px 2px rgba(0,0,0,0.04)' }
const thStyle = { textAlign: 'left', padding: 10, fontSize: 12, fontWeight: 600, color: '#444', background: '#FAFAFA', borderBottom: '1px solid #EEE' }
const tdStyle = { padding: 10, fontSize: 13, borderBottom: '1px solid #F2F2F2' }
const inputStyle = { padding: '8px 10px', borderRadius: 6, border: '1px solid #DDD', fontSize: 14 }

const btnStyle = (variant) => ({
  padding: variant === 'ghost' ? '4px 8px' : '6px 12px',
  border: 'none',
  borderRadius: 6,
  cursor: 'pointer',
  marginRight: 4,
  fontSize: 13,
  fontWeight: 500,
  ...(variant === 'primary'
    ? { background: '#E17A9D', color: 'white' }
    : variant === 'danger'
    ? { background: '#fff', color: '#D86B6B', border: '1px solid #D86B6B' }
    : { background: '#F0F0F0', color: '#333' }),
})
