'use client'

import { useState, useCallback, useEffect, useRef } from 'react'
import {
  Rocket,
  Gauge,
  Shield,
  Crosshair,
  CircuitBoard,
  Package,
  Cpu,
  Zap,
  Hammer,
  X,
  Plus,
  ShieldPlus,
  Swords,
  ArrowDownToLine,
} from 'lucide-react'
import { useGame } from '../GameProvider'
import { ProgressBar } from '../ProgressBar'
import { Panel, Modal, shared } from '../shared'
import { ItemName } from '../ItemTooltip'
import type { EnrichedShipModule } from '../types'
import { getItem as getCatalogRawItem, isModule } from '@/data/catalog'
import type { RawCatalogItem } from '@/data/catalog'
import { Check, AlertTriangle } from 'lucide-react'
import styles from './ShipPanel.module.css'

interface ShipClassDetail {
  name: string
  description: string
  lore: string
  category: string
  class: string
  tier: number
  faction: string
}

type SlotType = 'weapon' | 'defense' | 'utility'

export function ShipPanel() {
  const { state, sendCommand, api } = useGame()
  const ship = state.ship
  const isDocked = state.isDocked
  const actionPending = state.pendingAction !== null

  // Ship class details (description, lore)
  const [classDetail, setClassDetail] = useState<ShipClassDetail | null>(null)
  const fetchedClassId = useRef<string | null>(null)

  // Install modal
  const [installSlotType, setInstallSlotType] = useState<SlotType | null>(null)

  // Deposit controls (docked only) — per-item quantity + multi-select
  const [depositQtys, setDepositQtys] = useState<Record<string, string>>({})
  const [selectedCargo, setSelectedCargo] = useState<Record<string, boolean>>({})

  // Fetch ship class details from catalog
  useEffect(() => {
    if (!ship?.class_id || !api) return
    if (fetchedClassId.current === ship.class_id) return

    fetchedClassId.current = ship.class_id
    api.command('catalog', { type: 'ships', id: ship.class_id }).then((result) => {
      const r = result as Record<string, unknown>
      const items = (r.items || []) as Array<Record<string, unknown>>
      if (items.length > 0) {
        setClassDetail(items[0] as unknown as ShipClassDetail)
      }
    }).catch(() => { fetchedClassId.current = null })
  }, [ship?.class_id, api])

  const handleUninstallModule = useCallback(
    (moduleId: string) => {
      sendCommand('uninstall_mod', { module_id: moduleId })
    },
    [sendCommand]
  )

  const handleRepairModule = useCallback(
    (moduleId: string) => {
      sendCommand('repair_module', { module_id: moduleId })
    },
    [sendCommand]
  )

  const handleInstallModule = useCallback(
    (itemId: string) => {
      sendCommand('install_mod', { module_id: itemId }).then(() => {
        setInstallSlotType(null)
      })
    },
    [sendCommand]
  )

  const handleDepositItem = useCallback(
    (itemId: string, maxQty: number) => {
      if (actionPending) return
      const qtyStr = depositQtys[itemId] ?? String(maxQty)
      const quantity = parseInt(qtyStr, 10)
      if (isNaN(quantity) || quantity < 1 || quantity > maxQty) return
      sendCommand('deposit_items', { item_id: itemId, quantity })
      setDepositQtys((prev) => ({ ...prev, [itemId]: '' }))
      setSelectedCargo((prev) => {
        const next = { ...prev }
        delete next[itemId]
        return next
      })
    },
    [sendCommand, depositQtys, actionPending]
  )

  const handleDepositSelected = useCallback(() => {
    if (actionPending || !ship?.cargo) return
    // Loop through the selected items and fire one deposit_items call per item.
    // A bulk_deposit backend endpoint is planned as a follow-up.
    ship.cargo.forEach((item) => {
      if (!selectedCargo[item.item_id]) return
      const qtyStr = depositQtys[item.item_id] ?? String(item.quantity)
      const quantity = parseInt(qtyStr, 10)
      if (isNaN(quantity) || quantity < 1 || quantity > item.quantity) return
      sendCommand('deposit_items', { item_id: item.item_id, quantity })
    })
    setDepositQtys({})
    setSelectedCargo({})
  }, [sendCommand, ship, selectedCargo, depositQtys, actionPending])

  if (!ship) {
    return (
      <Panel title="Ship" icon={<Rocket size={16} />}>
        <div className={shared.emptyState}>No ship data available</div>
      </Panel>
    )
  }

  const modules = state.shipModules

  // Sort modules into slot columns
  const weaponMods = modules.filter(m => m.type === 'weapon')
  const defenseMods = modules.filter(m => m.type === 'defense')
  const utilityMods = modules.filter(m => m.type === 'mining' || m.type === 'utility')

  const weaponSlots = ship.weapon_slots ?? 0
  const defenseSlots = ship.defense_slots ?? 0
  const utilitySlots = ship.utility_slots ?? 0

  const emptyWeapon = Math.max(0, weaponSlots - weaponMods.length)
  const emptyDefense = Math.max(0, defenseSlots - defenseMods.length)
  const emptyUtility = Math.max(0, utilitySlots - utilityMods.length)

  // Get installable modules from cargo for a slot type
  const getInstallableModules = (slotType: SlotType): Array<{ item_id: string; name: string; quantity: number; catalogEntry?: RawCatalogItem }> => {
    if (!ship.cargo) return []

    return ship.cargo.flatMap(item => {
      const entry = getCatalogRawItem(item.item_id)
      if (!entry || !isModule(entry)) return []
      const modType = entry.type
      if (slotType === 'weapon' && modType !== 'weapon') return []
      if (slotType === 'defense' && modType !== 'defense') return []
      if (slotType === 'utility' && modType !== 'mining' && modType !== 'utility') return []
      return [{ item_id: item.item_id, name: item.name ?? item.item_id, quantity: item.quantity, catalogEntry: entry }]
    })
  }

  const renderModuleSlot = (mod: EnrichedShipModule, idx: number) => {
    const wear = mod.wear ?? 0
    const modInstanceId = mod.module_id || mod.id || ''
    return (
      <div key={modInstanceId || `mod-${idx}`} className={styles.slotFilled}>
        <div className={styles.slotModInfo}>
          <span className={styles.slotModName}><ItemName itemId={mod.type_id}>{mod.name}</ItemName></span>
          <div className={styles.slotModMeta}>
            {mod.cpu_usage > 0 && <span className={styles.slotStat}><Cpu size={9} /> {mod.cpu_usage}</span>}
            {mod.power_usage > 0 && <span className={styles.slotStat}><Zap size={9} /> {mod.power_usage}</span>}
            {mod.damage && <span className={styles.slotStat}><Swords size={9} /> {mod.damage}</span>}
            {mod.shield_bonus && <span className={styles.slotStat}><ShieldPlus size={9} /> +{mod.shield_bonus}</span>}
            {mod.mining_power && <span className={styles.slotStat}>⛏ {mod.mining_power}</span>}
            {mod.harvest_power && <span className={styles.slotStat}>⛏ {mod.harvest_power}</span>}
            {mod.scanner_power && <span className={styles.slotStat}>📡 {mod.scanner_power}</span>}
            {mod.cargo_bonus && <span className={styles.slotStat}><Package size={9} /> +{mod.cargo_bonus}</span>}
            {mod.speed_bonus && <span className={styles.slotStat}><Gauge size={9} /> +{mod.speed_bonus}</span>}
            {wear > 0 && <span className={styles.slotWear}>{mod.wear_status || `${Math.round(wear)}%`}</span>}
          </div>
        </div>
        <div className={styles.slotActions}>
          {isDocked && wear > 0 && (
            <button
              className={styles.repairModBtn}
              onClick={() => handleRepairModule(modInstanceId)}
              title="Repair module"
              type="button"
            >
              <Hammer size={11} />
            </button>
          )}
          {isDocked && (
            <button
              className={shared.dangerBtn}
              onClick={() => handleUninstallModule(modInstanceId)}
              title="Uninstall to cargo"
              type="button"
            >
              Uninstall
            </button>
          )}
        </div>
      </div>
    )
  }

  const renderEmptySlot = (slotType: SlotType, idx: number) => (
    <div
      key={`empty-${slotType}-${idx}`}
      className={`${styles.slotEmpty} ${isDocked ? styles.slotClickable : ''}`}
      onClick={isDocked ? () => setInstallSlotType(slotType) : undefined}
      title={isDocked ? 'Click to install a module' : 'Dock to install modules'}
    >
      <Plus size={14} className={styles.slotEmptyIcon} />
    </div>
  )

  return (
    <Panel title="Ship" icon={<Rocket size={16} />}>
        {/* Ship overview */}
        <div className={styles.shipOverview}>
          <img
            src={`/images/ships/catalog/${ship.class_id}.webp`}
            alt={ship.name}
            className={styles.shipImage}
            onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
          />
          <div className={styles.shipOverviewText}>
            <div className={styles.shipNameRow}>
              <span className={styles.shipClass}>{ship.name}</span>
              {ship.custom_name && (
                <span className={styles.shipName}>&quot;{ship.custom_name}&quot;</span>
              )}
              {classDetail && (
                <>
                  {classDetail.faction && <span className={shared.badgePurple}>{classDetail.faction}</span>}
                  {classDetail.tier > 0 && <span className={shared.badgeCyan}>T{classDetail.tier}</span>}
                  {classDetail.category && <span className={shared.badgeGreen}>{classDetail.category}</span>}
                  {classDetail.class && <span className={shared.badgeGrey}>{classDetail.class}</span>}
                </>
              )}
              <span className={styles.overviewStat}><Gauge size={10} /> {ship.speed}</span>
              {(ship.armor ?? 0) > 0 && (
                <span className={styles.overviewStat}><Shield size={10} /> {ship.armor}</span>
              )}
              {(ship.shield_recharge ?? 0) > 0 && (
                <span className={styles.overviewStat}><ShieldPlus size={10} /> {ship.shield_recharge}/t</span>
              )}
            </div>
            {classDetail?.description && (
              <div className={styles.shipDescription}>{classDetail.description}</div>
            )}
          </div>
        </div>

        {/* Lore */}
        {classDetail?.lore && (
          <div className={styles.shipLore}>{classDetail.lore}</div>
        )}

        {/* Stats grid */}
        <div className={styles.statsGrid}>
          <div className={styles.statCard}>
            <ProgressBar value={ship.hull} max={ship.max_hull} label="Hull" color="green" size="sm" />
          </div>
          <div className={styles.statCard}>
            <ProgressBar value={ship.shield ?? 0} max={ship.max_shield ?? 0} label="Shield" color="cyan" size="sm" />
          </div>
          <div className={styles.statCard}>
            <ProgressBar value={ship.cpu_used ?? 0} max={ship.cpu_capacity ?? 0} label="CPU" color="purple" size="sm" />
          </div>
          <div className={styles.statCard}>
            <ProgressBar value={ship.power_used ?? 0} max={ship.power_capacity ?? 0} label="Power" color="blue" size="sm" />
          </div>
        </div>

        {/* Module Slots — 3 columns */}
        <div className={shared.sectionTitle}>
          Modules
        </div>
        <div className={styles.slotGrid}>
          {/* Weapon column */}
          <div className={styles.slotColumn}>
            <div className={styles.slotColumnHeader}>
              <Crosshair size={12} /> Weapon ({weaponMods.length}/{weaponSlots})
            </div>
            {weaponMods.map((m, i) => renderModuleSlot(m, i))}
            {Array.from({ length: emptyWeapon }, (_, i) => renderEmptySlot('weapon', i))}
          </div>

          {/* Defense column */}
          <div className={styles.slotColumn}>
            <div className={styles.slotColumnHeader}>
              <Shield size={12} /> Defense ({defenseMods.length}/{defenseSlots})
            </div>
            {defenseMods.map((m, i) => renderModuleSlot(m, i))}
            {Array.from({ length: emptyDefense }, (_, i) => renderEmptySlot('defense', i))}
          </div>

          {/* Utility column */}
          <div className={styles.slotColumn}>
            <div className={styles.slotColumnHeader}>
              <CircuitBoard size={12} /> Utility ({utilityMods.length}/{utilitySlots})
            </div>
            {utilityMods.map((m, i) => renderModuleSlot(m, i))}
            {Array.from({ length: emptyUtility }, (_, i) => renderEmptySlot('utility', i))}
          </div>
        </div>

        {/* Cargo Hold */}
        <div className={shared.sectionTitle}>
          <Package size={12} />
          Cargo Hold ({ship.cargo_used ?? 0}/{ship.cargo_capacity})
        </div>
        {ship.cargo && ship.cargo.length > 0 ? (
          <>
            <div className={styles.cargoList}>
              {ship.cargo.map((item) => {
                const rawItem = getCatalogRawItem(item.item_id)
                const modEntry = rawItem && isModule(rawItem) ? rawItem : null
                let compatStatus: { ok: boolean; reason?: string } | null = null
                if (modEntry && isDocked) {
                  const cpuFree = (ship.cpu_capacity ?? 0) - (ship.cpu_used ?? 0)
                  const powerFree = (ship.power_capacity ?? 0) - (ship.power_used ?? 0)
                  const slotType = modEntry.type
                  let slotsUsed = 0
                  let slotsTotal = 0
                  if (slotType === 'weapon') {
                    slotsUsed = weaponMods.length
                    slotsTotal = weaponSlots
                  } else if (slotType === 'defense') {
                    slotsUsed = defenseMods.length
                    slotsTotal = defenseSlots
                  } else {
                    slotsUsed = utilityMods.length
                    slotsTotal = utilitySlots
                  }
                  const cpu = modEntry.cpu_usage ?? 0
                  const power = modEntry.power_usage ?? 0
                  if (cpu > cpuFree) {
                    compatStatus = { ok: false, reason: `Needs ${cpu} CPU, ${cpuFree} free` }
                  } else if (power > powerFree) {
                    compatStatus = { ok: false, reason: `Needs ${power} power, ${powerFree} free` }
                  } else if (slotsUsed >= slotsTotal) {
                    const label = slotType === 'mining' || slotType === 'utility' ? 'utility' : slotType
                    compatStatus = { ok: false, reason: `No ${label} slots free` }
                  } else {
                    compatStatus = { ok: true }
                  }
                }
                const qtyStr = depositQtys[item.item_id] ?? String(item.quantity)
                const qtyNum = parseInt(qtyStr, 10)
                const qtyValid = !isNaN(qtyNum) && qtyNum >= 1 && qtyNum <= item.quantity
                const checked = !!selectedCargo[item.item_id]
                return (
                  <div key={item.item_id} className={styles.cargoItem}>
                    <div className={styles.cargoNameWrap}>
                      {isDocked && (
                        <input
                          type="checkbox"
                          className={styles.cargoSelect}
                          checked={checked}
                          onChange={(e) =>
                            setSelectedCargo((prev) => ({
                              ...prev,
                              [item.item_id]: e.target.checked,
                            }))
                          }
                          title="Select for Move Selected"
                        />
                      )}
                      <span className={styles.cargoName}>
                        <ItemName itemId={item.item_id}>{item.name ?? item.item_id}</ItemName>
                      </span>
                    </div>
                    <span className={styles.cargoMeta}>
                      {compatStatus && (
                        compatStatus.ok ? (
                          <span className={styles.compatOk} title="Can install"><Check size={10} /></span>
                        ) : (
                          <span className={styles.compatNo} title={compatStatus.reason}><AlertTriangle size={10} /> {compatStatus.reason}</span>
                        )
                      )}
                      <span className={styles.cargoQty}>x{item.quantity}</span>
                      <span className={styles.cargoSize}>{item.quantity * (item.size ?? 0)}u</span>
                      {isDocked && (
                        <span className={styles.cargoDepositAction}>
                          <input
                            className={styles.cargoQtyInput}
                            type="number"
                            min={1}
                            max={item.quantity}
                            value={qtyStr}
                            onChange={(e) =>
                              setDepositQtys((prev) => ({
                                ...prev,
                                [item.item_id]: e.target.value,
                              }))
                            }
                            title="Quantity to move to storage"
                          />
                          <button
                            className={shared.confirmBtn}
                            onClick={() => handleDepositItem(item.item_id, item.quantity)}
                            disabled={actionPending || !qtyValid}
                            title={actionPending ? 'Another action is pending' : 'Move to station storage'}
                            type="button"
                          >
                            <ArrowDownToLine size={10} />
                          </button>
                        </span>
                      )}
                    </span>
                  </div>
                )
              })}
            </div>
            {isDocked && (
              <div className={styles.cargoBulkRow}>
                <span className={styles.cargoBulkHint}>
                  {Object.values(selectedCargo).filter(Boolean).length} selected
                </span>
                <button
                  className={shared.confirmBtn}
                  onClick={handleDepositSelected}
                  disabled={
                    actionPending ||
                    Object.values(selectedCargo).filter(Boolean).length === 0
                  }
                  title={
                    actionPending
                      ? 'Another action is pending'
                      : 'Move all selected items to station storage'
                  }
                  type="button"
                >
                  <ArrowDownToLine size={10} /> Move Selected to Storage
                </button>
              </div>
            )}
          </>
        ) : (
          <div className={shared.emptyState}>Cargo hold is empty</div>
        )}

      {/* Install module modal */}
      {installSlotType && (
        <InstallModuleModal
          slotType={installSlotType}
          modules={getInstallableModules(installSlotType)}
          onInstall={handleInstallModule}
          onClose={() => setInstallSlotType(null)}
          cpuAvailable={(ship.cpu_capacity ?? 0) - (ship.cpu_used ?? 0)}
          powerAvailable={(ship.power_capacity ?? 0) - (ship.power_used ?? 0)}
        />
      )}
    </Panel>
  )
}

function InstallModuleModal({ slotType, modules, onInstall, onClose, cpuAvailable, powerAvailable }: {
  slotType: SlotType
  modules: Array<{ item_id: string; name: string; quantity: number; catalogEntry?: RawCatalogItem }>
  onInstall: (itemId: string) => void
  onClose: () => void
  cpuAvailable: number
  powerAvailable: number
}) {
  const slotLabel = slotType === 'utility' ? 'Utility / Mining' : slotType.charAt(0).toUpperCase() + slotType.slice(1)

  return (
    <Modal title={`Install ${slotLabel} Module`} onClose={onClose}>
      <div className={styles.modalCapacity}>
        <span><Cpu size={11} /> CPU: {cpuAvailable} free</span>
        <span><Zap size={11} /> Power: {powerAvailable} free</span>
      </div>
      {modules.length === 0 ? (
        <div className={shared.emptyState}>
          No compatible modules in cargo
        </div>
      ) : (
        <div className={styles.installList}>
          {modules.map((mod) => {
            const cat = mod.catalogEntry
            const fitsResources = cat
              ? ((cat.cpu_usage ?? 0) <= cpuAvailable && (cat.power_usage ?? 0) <= powerAvailable)
              : true
            return (
              <div key={mod.item_id} className={styles.installItem}>
                <div className={styles.installInfo}>
                  <span className={styles.installName}>{mod.name}</span>
                  <div className={styles.installMeta}>
                    <span className={styles.installQty}>x{mod.quantity}</span>
                    {cat && (
                      <>
                        <span className={styles.slotStat}><Cpu size={9} /> {cat.cpu_usage}</span>
                        <span className={styles.slotStat}><Zap size={9} /> {cat.power_usage}</span>
                        {cat.damage && <span className={styles.slotStat}><Swords size={9} /> {cat.damage}</span>}
                        {cat.shield_bonus && <span className={styles.slotStat}><ShieldPlus size={9} /> +{cat.shield_bonus}</span>}
                        {cat.mining_power && <span className={styles.slotStat}>⛏ {cat.mining_power}</span>}
                      </>
                    )}
                  </div>
                  {!fitsResources && (
                    <span className={styles.installWarning}>Insufficient CPU or power</span>
                  )}
                </div>
                <button
                  className={shared.actionBtn}
                  onClick={() => onInstall(mod.item_id)}
                  disabled={!fitsResources}
                  type="button"
                >
                  <Plus size={12} /> Install
                </button>
              </div>
            )
          })}
        </div>
      )}
    </Modal>
  )
}
