import { useState } from 'react'
import { Link } from 'react-router-dom'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import api from '../utils/api'
import { formatDistance, formatDuration, formatDate, formatPace, sportIcon } from '../utils/format'

// Decode Google encoded polyline to [[lat,lng], ...]
function decodePolyline(encoded) {
  if (!encoded) return []
  const points = []
  let idx = 0, lat = 0, lng = 0
  while (idx < encoded.length) {
    let shift = 0, result = 0, byte
    do { byte = encoded.charCodeAt(idx++) - 63; result |= (byte & 0x1f) << shift; shift += 5 } while (byte >= 0x20)
    lat += result & 1 ? ~(result >> 1) : result >> 1
    shift = 0; result = 0
    do { byte = encoded.charCodeAt(idx++) - 63; result |= (byte & 0x1f) << shift; shift += 5 } while (byte >= 0x20)
    lng += result & 1 ? ~(result >> 1) : result >> 1
    points.push([lat / 1e5, lng / 1e5])
  }
  return points
}

function RouteMap({ polyline, className = '' }) {
  const pts = decodePolyline(polyline)
  if (pts.length < 2) return (
    <div className={`bg-gray-800 rounded flex items-center justify-center text-gray-600 text-xs ${className}`}>
      no track
    </div>
  )
  const lats = pts.map(p => p[0]), lngs = pts.map(p => p[1])
  const minLat = Math.min(...lats), maxLat = Math.max(...lats)
  const minLng = Math.min(...lngs), maxLng = Math.max(...lngs)
  const rangeL = maxLng - minLng || 1e-5
  const rangeA = maxLat - minLat || 1e-5
  const pad = 4
  const w = 100, h = 60
  const toX = lng => pad + ((lng - minLng) / rangeL) * (w - pad * 2)
  const toY = lat => pad + ((maxLat - lat) / rangeA) * (h - pad * 2)
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${toX(p[1]).toFixed(1)},${toY(p[0]).toFixed(1)}`).join(' ')
  return (
    <svg viewBox={`0 0 ${w} ${h}`} className={`bg-gray-800 rounded ${className}`} xmlns="http://www.w3.org/2000/svg">
      <path d={d} fill="none" stroke="#3b82f6" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  )
}

export default function RoutesPage() {
  const [selected, setSelected] = useState(null)
  const [showCreate, setShowCreate] = useState(false)
  const [newRoute, setNewRoute] = useState({ name: '', activity_id: '' })
  const [merging, setMerging] = useState(false)
  const [mergeTarget, setMergeTarget] = useState('')
  const qc = useQueryClient()

  const { data: routes } = useQuery({
    queryKey: ['routes'],
    queryFn: () => api.get('/routes/').then(r => r.data),
  })

  const { data: routeActivities } = useQuery({
    queryKey: ['route-activities', selected?.id],
    queryFn: () => api.get(`/routes/${selected.id}/activities`).then(r => r.data),
    enabled: !!selected,
  })

  const { data: recentActivities } = useQuery({
    queryKey: ['recent-activities-for-route'],
    queryFn: () => api.get('/routes/recent-activities').then(r => r.data),
    enabled: showCreate,
  })

  const createRoute = useMutation({
    mutationFn: data => api.post('/routes/', data).then(r => r.data),
    onSuccess: route => {
      qc.invalidateQueries({ queryKey: ['routes'] })
      setShowCreate(false)
      setNewRoute({ name: '', activity_id: '' })
      setSelected(route)
    },
  })

  const mergeRoute = useMutation({
    mutationFn: ({ into, from }) => api.post(`/routes/${into}/merge/${from}`).then(r => r.data),
    onSuccess: updated => {
      qc.invalidateQueries({ queryKey: ['routes'] })
      qc.invalidateQueries({ queryKey: ['route-activities', updated.id] })
      setMerging(false)
      setMergeTarget('')
      setSelected(updated)
    },
  })

  const deleteRoute = useMutation({
    mutationFn: id => api.delete(`/routes/${id}`),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['routes'] })
      setSelected(null)
    },
  })

  const fastest = routeActivities?.[0]
  const otherRoutes = routes?.filter(r => r.id !== selected?.id && r.sport_type === selected?.sport_type) ?? []

  return (
    <div className="p-6 space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Named Routes</h1>
          <p className="text-xs text-gray-500 mt-1">
            Routes are auto-detected when you run the same path twice. You can also create them manually.
          </p>
        </div>
        <button onClick={() => setShowCreate(true)}
          className="bg-blue-600 hover:bg-blue-700 text-white text-sm px-4 py-2 rounded-lg transition-colors">
          + New route
        </button>
      </div>

      {/* Create route panel */}
      {showCreate && (
        <div className="bg-gray-900 border border-gray-700 rounded-xl p-5 space-y-4">
          <h3 className="text-sm font-semibold text-white">Create named route</h3>
          <p className="text-xs text-gray-500">
            Select an activity to use as the reference GPS track. Future activities on the same route will be linked automatically.
          </p>
          <div className="space-y-3">
            <div>
              <label className="text-xs text-gray-400 mb-1 block">Route name</label>
              <input value={newRoute.name} onChange={e => setNewRoute(r => ({ ...r, name: e.target.value }))}
                className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
                placeholder="e.g. Morning park loop" />
            </div>
            <div>
              <label className="text-xs text-gray-400 mb-1 block">Reference activity (last 2 weeks)</label>
              <select value={newRoute.activity_id} onChange={e => setNewRoute(r => ({ ...r, activity_id: e.target.value }))}
                className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:ring-2 focus:ring-blue-500">
                <option value="">Select an activity…</option>
                {recentActivities?.map(a => (
                  <option key={a.id} value={a.id}>
                    {sportIcon(a.sport_type)} {a.name} — {formatDistance(a.distance_m)} on {formatDate(a.start_time)}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <div className="flex gap-3">
            <button onClick={() => createRoute.mutate({ ...newRoute, activity_id: parseInt(newRoute.activity_id) })}
              disabled={!newRoute.name || !newRoute.activity_id || createRoute.isPending}
              className="bg-blue-600 hover:bg-blue-700 disabled:opacity-40 text-white text-sm px-4 py-2 rounded-lg transition-colors">
              Create
            </button>
            <button onClick={() => setShowCreate(false)}
              className="text-gray-400 hover:text-white text-sm px-4 py-2 rounded-lg transition-colors">
              Cancel
            </button>
          </div>
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        {/* Route list */}
        <div className="space-y-2">
          {routes?.length === 0 && !showCreate && (
            <div className="text-center py-12 text-gray-600">
              <p className="text-3xl mb-2">🗺️</p>
              <p className="text-sm">No named routes yet</p>
              <p className="text-xs mt-1">Routes are created automatically when you repeat a run, or create one manually above.</p>
            </div>
          )}
          {routes?.map(route => (
            <button key={route.id} onClick={() => { setSelected(route); setMerging(false) }}
              className={`w-full text-left p-3 rounded-xl border transition-all ${
                selected?.id === route.id ? 'bg-blue-900/20 border-blue-700' : 'bg-gray-900 border-gray-800 hover:border-gray-600'
              }`}>
              <div className="flex gap-3 items-start">
                <RouteMap polyline={route.reference_polyline} className="w-20 h-12 flex-shrink-0" />
                <div className="min-w-0 flex-1">
                  <div className="flex items-start justify-between gap-1">
                    <p className="font-medium text-white text-sm truncate">{route.name}</p>
                    {route.auto_detected && (
                      <span className="text-xs bg-gray-800 text-gray-400 px-1.5 py-0.5 rounded-full flex-shrink-0">auto</span>
                    )}
                  </div>
                  <div className="flex gap-2 mt-0.5 text-xs text-gray-500">
                    <span>{formatDistance(route.distance_m)}</span>
                    {route.sport_type && <span className="capitalize">{route.sport_type}</span>}
                  </div>
                </div>
              </div>
            </button>
          ))}
        </div>

        {/* Route detail */}
        {selected && (
          <div className="lg:col-span-2 space-y-4">
            <div className="bg-gray-900 rounded-xl border border-gray-800 p-5">
              <div className="flex items-start justify-between mb-4">
                <div className="flex gap-4 items-start">
                  <RouteMap polyline={selected.reference_polyline} className="w-36 h-24 flex-shrink-0" />
                  <div>
                    <h2 className="text-lg font-semibold text-white">{selected.name}</h2>
                    <div className="flex flex-wrap gap-2 mt-1 text-xs text-gray-500">
                      {selected.sport_type && <span className="capitalize">{selected.sport_type}</span>}
                      <span>{formatDistance(selected.distance_m)}</span>
                      {selected.auto_detected && (
                        <span className="text-blue-400 border border-blue-700/40 px-1.5 py-0.5 rounded-full">Auto-detected</span>
                      )}
                    </div>
                  </div>
                </div>
                <div className="flex gap-2 flex-shrink-0">
                  <button onClick={() => { setMerging(m => !m); setMergeTarget('') }}
                    className="text-xs bg-gray-800 hover:bg-gray-700 text-gray-300 px-3 py-1.5 rounded-lg transition-colors">
                    Merge
                  </button>
                  <button
                    onClick={() => { if (confirm(`Delete "${selected.name}"? Activities will be unlinked.`)) deleteRoute.mutate(selected.id) }}
                    className="text-xs text-red-500 hover:text-red-400 px-2 py-1.5 rounded-lg transition-colors">
                    Delete
                  </button>
                </div>
              </div>

              {/* Merge panel */}
              {merging && (
                <div className="mb-4 bg-yellow-900/20 border border-yellow-700/40 rounded-lg p-3 space-y-2">
                  <p className="text-xs text-yellow-400 font-medium">Merge another route into this one</p>
                  <p className="text-xs text-gray-500">All activities from the selected route will be moved here, then the other route will be deleted.</p>
                  <div className="flex gap-2">
                    <select value={mergeTarget} onChange={e => setMergeTarget(e.target.value)}
                      className="flex-1 bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-sm text-white focus:outline-none focus:ring-2 focus:ring-yellow-500">
                      <option value="">Select route to merge in…</option>
                      {otherRoutes.map(r => (
                        <option key={r.id} value={r.id}>{r.name} ({formatDistance(r.distance_m)})</option>
                      ))}
                    </select>
                    <button
                      disabled={!mergeTarget || mergeRoute.isPending}
                      onClick={() => mergeRoute.mutate({ into: selected.id, from: parseInt(mergeTarget) })}
                      className="bg-yellow-600 hover:bg-yellow-700 disabled:opacity-40 text-white text-sm px-4 py-2 rounded-lg transition-colors">
                      Merge
                    </button>
                    <button onClick={() => setMerging(false)}
                      className="text-gray-400 hover:text-white text-sm px-3 py-2 rounded-lg transition-colors">
                      Cancel
                    </button>
                  </div>
                  {otherRoutes.length === 0 && (
                    <p className="text-xs text-gray-600">No other {selected.sport_type} routes to merge with.</p>
                  )}
                </div>
              )}

              {/* Course record */}
              {fastest && (
                <div className="bg-yellow-900/20 border border-yellow-700/40 rounded-lg p-3 mb-4">
                  <p className="text-xs text-yellow-600 mb-1">Course record 🏆</p>
                  <div className="flex items-center gap-4">
                    <span className="text-xl font-bold text-yellow-400">{formatDuration(fastest.duration_s)}</span>
                    <span className="text-sm text-gray-400">
                      {formatDate(fastest.start_time)} · {formatPace(fastest.avg_speed_ms, selected.sport_type)}
                    </span>
                  </div>
                </div>
              )}

              {/* Activity list */}
              <h3 className="text-sm font-medium text-gray-400 mb-2">
                All runs ({routeActivities?.length ?? 0})
              </h3>
              <div className="space-y-1">
                {routeActivities?.map((act, i) => (
                  <Link key={act.id} to={`/activities/${act.id}`}
                    className="flex items-center gap-4 px-2 py-2 rounded-lg hover:bg-gray-800/60 transition-colors text-sm group">
                    <span className="text-gray-600 w-5 text-right flex-shrink-0">{i + 1}</span>
                    <span className="text-gray-400 flex-1">{formatDate(act.start_time)}</span>
                    <span className="font-mono text-white font-medium">{formatDuration(act.duration_s)}</span>
                    <span className="text-gray-500">{formatPace(act.avg_speed_ms, selected.sport_type)}</span>
                    {act.avg_heart_rate && (
                      <span className="text-red-400 text-xs">{Math.round(act.avg_heart_rate)} bpm</span>
                    )}
                    {i === 0 && (
                      <span className="text-xs bg-yellow-900/40 text-yellow-400 px-2 py-0.5 rounded-full border border-yellow-700/40">CR</span>
                    )}
                    <span className="text-gray-700 group-hover:text-gray-400 text-xs transition-colors">→</span>
                  </Link>
                ))}
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}
