import { useCallback, useEffect, useState } from 'react'
import { api } from '../api'
import { ACCEPT_GLYPH, REJECT_GLYPH } from './Thumbs'

// Expiry convention, in one place for the create form and the row editor:
// end of the chosen day in the photographer's local timezone — date-only
// strings would parse as UTC midnight and expire a day early. Half-typed
// years (Safari fires change with e.g. 0002) count as "no expiry".
const endOfDayIso = (day) =>
  !day || day.slice(0, 4) < '2000' ? null : new Date(`${day}T23:59:59`).toISOString()

const localDate = (iso) => {
  const d = new Date(iso)
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

// Staged expiry editor: commits on blur/Enter, never per keystroke. Renders
// "never" until an expiry exists or the user asks for one — an empty date
// input is not shown at all (Safari fills it with today's date as a
// pseudo-placeholder, which reads like a set expiry).
function ExpiryDate({ value, onCommit }) {
  const current = value ? localDate(value) : ''
  const [draft, setDraft] = useState(current)
  const [editing, setEditing] = useState(false)
  useEffect(() => setDraft(current), [current])

  const commit = () => {
    setEditing(false)
    if (draft === current) return
    const iso = endOfDayIso(draft)
    if (draft && !iso) {
      setDraft(current)
      return
    }
    onCommit(iso)
  }

  if (!value && !editing) {
    return (
      <label className="row field-label">
        <span className="muted">expires</span>
        <button
          type="button"
          className="btn btn-ghost"
          title="Set an expiry date"
          onClick={() => setEditing(true)}
        >
          never
        </button>
      </label>
    )
  }

  return (
    <label className="row field-label">
      <span className="muted">expires</span>
      <input
        type="date"
        autoFocus={editing}
        value={draft}
        onChange={(e) => setDraft(e.target.value)}
        onBlur={commit}
        onKeyDown={(e) => {
          if (e.key === 'Enter') e.target.blur()
        }}
      />
      {value && (
        <button
          type="button"
          className="btn btn-ghost"
          title="Remove expiry — link never expires"
          onClick={() => {
            setDraft('')
            setEditing(false)
            onCommit(null)
          }}
        >
          ✕
        </button>
      )}
    </label>
  )
}

export default function SharesPanel({ albumId }) {
  const [shares, setShares] = useState([])
  const [form, setForm] = useState({ label: '', password: '', allow_download: true, expires_at: '' })
  const [expiryOpen, setExpiryOpen] = useState(false)
  const [error, setError] = useState(null)
  const [copied, setCopied] = useState(null)

  const load = useCallback(
    () => api(`/api/albums/${albumId}/shares`).then(setShares).catch((e) => setError(e.message)),
    [albumId],
  )
  useEffect(() => {
    load()
  }, [load])

  const create = async (e) => {
    e.preventDefault()
    try {
      await api(`/api/albums/${albumId}/shares`, {
        method: 'POST',
        body: {
          label: form.label,
          password: form.password || null,
          allow_download: form.allow_download,
          expires_at: endOfDayIso(form.expires_at),
        },
      })
      setForm({ label: '', password: '', allow_download: true, expires_at: '' })
      setExpiryOpen(false)
      setError(null)
      load()
    } catch (e) {
      setError(e.message)
    }
  }

  const copy = async (share) => {
    await navigator.clipboard.writeText(share.url)
    setCopied(share.id)
    setTimeout(() => setCopied(null), 1500)
  }

  const update = async (shareId, patch) => {
    try {
      const updated = await api(`/api/shares/${shareId}`, { method: 'PATCH', body: patch })
      setShares((list) => list.map((s) => (s.id === shareId ? updated : s)))
      setError(null)
    } catch (e) {
      setError(e.message)
      // Re-sync the controlled inputs with what the server actually has.
      load()
    }
  }

  return (
    <div>
      {shares.length === 0 && <p className="muted">No links yet.</p>}
      {shares.map((s) => (
        <div key={s.id} className="share-row">
          <div className="share-info">
            <span className="row">
              <strong>{s.label || 'unnamed link'}</strong>
              {s.has_password && <span title="Password protected">🔒</span>}
              {s.locked && (
                <>
                  <span className="error">locked (too many wrong passwords)</span>
                  <button
                    className="btn"
                    onClick={async () => {
                      await api(`/api/shares/${s.id}/reset-lock`, { method: 'POST' })
                      load()
                    }}
                  >
                    Unlock
                  </button>
                </>
              )}
            </span>
            <button className="share-url" title="Copy link" onClick={() => copy(s)}>
              {copied === s.id ? 'Copied!' : s.url.replace(/^https?:\/\//, '')}
            </button>
            {s.accept_count + s.reject_count + s.rating_count + s.tag_count > 0 && (
              <span className="row share-feedback">
                <span className="share-stats">
                  {s.accept_count > 0 && (
                    <span className="chip chip-accept">
                      {ACCEPT_GLYPH} {s.accept_count}
                    </span>
                  )}
                  {s.reject_count > 0 && (
                    <span className="chip chip-reject">
                      {REJECT_GLYPH} {s.reject_count}
                    </span>
                  )}
                  {s.rating_count > 0 && <span className="chip">★ {s.rating_count}</span>}
                  {s.tag_count > 0 && <span className="chip"># {s.tag_count}</span>}
                </span>
              </span>
            )}
          </div>
          <div className="row share-controls">
            <label className="select-toggle" title="Allow this link to download originals/ZIPs">
              <input
                type="checkbox"
                checked={s.allow_download}
                onChange={(e) => update(s.id, { allow_download: e.target.checked })}
              />
              downloads
            </label>
            <ExpiryDate value={s.expires_at} onCommit={(iso) => update(s.id, { expires_at: iso })} />
            <button className="btn" onClick={() => copy(s)}>
              {copied === s.id ? 'Copied!' : 'Copy link'}
            </button>
            <button
              className="btn btn-danger"
              title="Delete link — removes its votes, ratings and tags too"
              onClick={async () => {
                if (!confirm(`Delete link "${s.label || s.token}"? Client votes, ratings and tags from this link are removed too.`)) return
                await api(`/api/shares/${s.id}`, { method: 'DELETE' })
                load()
              }}
            >
              Delete
            </button>
          </div>
        </div>
      ))}
      <form className="share-form" onSubmit={create}>
        <h3 className="share-form-title">New link</h3>
        <label className="field">
          <span className="muted">Label</span>
          <input
            placeholder="e.g. client name"
            value={form.label}
            onChange={(e) => setForm({ ...form, label: e.target.value })}
          />
        </label>
        <label className="field">
          <span className="muted">Password</span>
          <input
            placeholder="optional"
            value={form.password}
            onChange={(e) => setForm({ ...form, password: e.target.value })}
          />
        </label>
        <label className="field">
          <span className="muted">Expires</span>
          <span className="row">
            {form.expires_at || expiryOpen ? (
              <>
                <input
                  type="date"
                  autoFocus={expiryOpen && !form.expires_at}
                  value={form.expires_at}
                  onChange={(e) => setForm({ ...form, expires_at: e.target.value })}
                />
                <button
                  type="button"
                  className="btn btn-ghost"
                  title="No expiry — link never expires"
                  onClick={() => {
                    setExpiryOpen(false)
                    setForm({ ...form, expires_at: '' })
                  }}
                >
                  ✕
                </button>
              </>
            ) : (
              <button
                type="button"
                className="btn btn-ghost"
                title="Set an expiry date"
                onClick={() => setExpiryOpen(true)}
              >
                never
              </button>
            )}
          </span>
        </label>
        <label className="field">
          <span className="muted">Downloads</span>
          <input
            type="checkbox"
            checked={form.allow_download}
            onChange={(e) => setForm({ ...form, allow_download: e.target.checked })}
          />
        </label>
        <div className="share-form-full">
          <button className="btn btn-primary" type="submit">
            Create link
          </button>
        </div>
      </form>
      {error && <p className="error">{error}</p>}
    </div>
  )
}
