import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import type {
  OrgInfoPayload,
  OrgCreateMemberInput,
  OrgSavedCreatePayload,
  SavedOrgSummary,
  TalentTemplate,
  EmployeeDetailPayload,
  ReorgProposalInfo,
  ArchitecturePreset,
  ArchitecturePresetDetail,
  HireTalentHandler,
} from '../types/visual'
import { TeamView } from './TeamView'
import { DelegationStrategyPanel } from './DelegationStrategyPanel'
import { ArchitectureMarketplace } from './ArchitectureMarketplace'
import { EmployeesMarketplace } from './EmployeesMarketplace'
import { ConfigImportExportPanel } from './ConfigImportExportPanel'
import { OrgCreateModal } from './OrgCreateModal'
import { getRuntimeOrgView } from '../lib/runtimeOrg'
import './org.css'
import './team.css'
import './marketplace.css'
import './config.css'
import './structure.css'

/* ── Inline SVG icon data-URIs (no external CDN) ────────────────── */
const TAB_ICON = {
  team: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z'/%3E%3C/svg%3E",
  runtime: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M13 2.05v2.02c3.95.49 7 3.85 7 7.93 0 3.21-1.81 6-4.72 7.72L13 17v5h5l-1.22-1.22C19.91 19.07 22 15.76 22 12c0-5.18-3.95-9.45-9-9.95zM11 2.05C5.95 2.55 2 6.82 2 12c0 3.76 2.09 7.07 5.22 8.78L6 22h5V2.05z'/%3E%3C/svg%3E",
  architecture: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E",
  employees: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E",
}
const STAT_ICON = {
  agents: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M20 9V7c0-1.1-.9-2-2-2h-3c0-1.66-1.34-3-3-3S9 3.34 9 5H6c-1.1 0-2 .9-2 2v2c-1.66 0-3 1.34-3 3s1.34 3 3 3v4c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-4c1.66 0 3-1.34 3-3s-1.34-3-3-3z'/%3E%3C/svg%3E",
  active: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%2322c55e' d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z'/%3E%3C/svg%3E",
}
const SECTION_ICON = {
  packages: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M20.54 5.23l-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5L6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z'/%3E%3C/svg%3E",
  channels: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E",
  reorg: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z'/%3E%3C/svg%3E",
  importPkg: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23888' d='M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z'/%3E%3C/svg%3E",
}

type SubTab = 'team' | 'runtime' | 'architecture' | 'employees'

function humanizeOrgName(value?: string | null): string {
  const normalized = String(value ?? '').trim()
  if (!normalized) return ''
  return normalized
    .replace(/^org[_-]/i, '')
    .replace(/[_-]+/g, ' ')
    .replace(/\s+/g, ' ')
    .trim()
    .replace(/\b\w/g, char => char.toUpperCase())
}

interface OrgTabProps {
  data: OrgInfoPayload | null
  /** role_id -> recruited names for the selected session (canvas display only). */
  sessionRecruitmentByRole?: Record<string, string[]> | null
  talents: TalentTemplate[]
  employeeDetail: EmployeeDetailPayload | null
  reorgProposals: ReorgProposalInfo[]
  isCustomMode?: boolean
  onRequestData: () => void
  onRequestTalents: () => void
  onRequestEmployeeDetail: (employeeId: string) => void
  onHireTalent: HireTalentHandler
  hiringTemplateId?: string | null
  onImportEmployee?: (employeeId: string) => void
  onRequestReorgList: () => void
  onReorgDecide: (proposalId: string, approved: boolean, notes?: string) => void
  // Market
  onMarketExport?: (data: { package_id: string; name: string; description: string; version: string }) => void
  onMarketInstall?: (path: string, strategy: string) => void
  onMarketUninstall?: (packageId: string) => void
  // Architecture gallery
  marketPresets?: ArchitecturePreset[]
  marketPreviewData?: ArchitecturePresetDetail | null
  onMarketBrowse?: () => void
  onMarketPreview?: (presetId: string) => void
  onMarketApplyPreset?: (presetId: string, strategy: string) => void
  onMarketClearPreview?: () => void
  // Config import/export
  onConfigExport?: () => void
  onConfigImport?: (yaml: string, dryRun: boolean) => void
  configExportYaml?: string | null
  configImportPreview?: { roles_added: number; roles_removed: number; employees_changed: number } | null
  configImportError?: string | null
  // Saved org architectures (named snapshots) — rendered in the Team tab toolbar
  onSavedOrgsList?: () => void
  onSavedOrgSaveAs?: (name: string, overwrite: boolean) => void
  onSavedOrgCreate?: (organizationName: string, members: OrgCreateMemberInput[]) => void
  onSavedOrgLoad?: (name: string) => void
  onSavedOrgDelete?: (name: string) => void
  savedOrgsList?: SavedOrgSummary[] | null
  activeSavedOrg?: string | null
  activeSavedOrgVersionAtLoad?: number | null
  orgCreatePending?: boolean
  orgCreateResult?: (OrgSavedCreatePayload & { nonce: number }) | null
  onSelectCorporate?: () => void
  // Org editing
  onAddRole?: (roleId: string, name: string, responsibility: string, reportsTo: string, icon?: string | null) => void
  onBulkAddRoles?: (roles: Array<{ role_id: string; name: string; responsibility: string; reports_to: string }>) => void
  onUpdateRole?: (roleId: string, updates: { name?: string; responsibility?: string; reports_to?: string; can_spawn?: string[]; icon?: string | null; execution_strategy?: string; preferred_external_agent?: string | null; prompt_refs?: string[] }) => void
  onDeleteRole?: (roleId: string) => void
  onUpdateOrgStrategy?: (data: { final_decider_role_id?: string | null }) => void
  onUpdateRuntimePolicy?: (policy: Record<string, any>) => void
  onResetArchitecture?: () => void
}

export function OrgTab({
  data, sessionRecruitmentByRole, talents, employeeDetail, reorgProposals, isCustomMode,
  onRequestData, onRequestTalents, onRequestEmployeeDetail,
  onHireTalent, hiringTemplateId, onImportEmployee, onRequestReorgList, onReorgDecide,
  onMarketExport, onMarketInstall, onMarketUninstall,
  marketPresets, marketPreviewData, onMarketBrowse, onMarketPreview, onMarketApplyPreset, onMarketClearPreview,
  onAddRole, onBulkAddRoles, onUpdateRole, onDeleteRole, onUpdateOrgStrategy,
  onUpdateRuntimePolicy, onResetArchitecture,
  onConfigExport, onConfigImport, configExportYaml, configImportPreview, configImportError,
  onSavedOrgsList, onSavedOrgSaveAs, onSavedOrgCreate, onSavedOrgLoad, onSavedOrgDelete, savedOrgsList,
  activeSavedOrg, activeSavedOrgVersionAtLoad, orgCreatePending, orgCreateResult, onSelectCorporate,
}: OrgTabProps) {
  const [activeTab, setActiveTab] = useState<SubTab>('team')
  const [createOpen, setCreateOpen] = useState(false)

  const switchTab = useCallback((tab: SubTab) => {
    setActiveTab(tab)
  }, [])
  const [applyingPresetId, setApplyingPresetId] = useState<string | null>(null)
  const versionAtApply = useRef<number>(-1) // track org_version when apply starts
  const [toast, setToast] = useState<{ msg: string; type: 'info' | 'warn' } | null>(null)
  const toastTimer = useRef<ReturnType<typeof setTimeout>>(null)

  const showToast = useCallback((msg: string, type: 'info' | 'warn' = 'info') => {
    setToast({ msg, type })
    if (toastTimer.current) clearTimeout(toastTimer.current)
    toastTimer.current = setTimeout(() => setToast(null), 3000)
  }, [])

  useEffect(() => () => {
    if (toastTimer.current) clearTimeout(toastTimer.current)
  }, [])

  const onRequestDataRef = useRef(onRequestData)
  const onRequestTalentsRef = useRef(onRequestTalents)
  const onRequestReorgListRef = useRef(onRequestReorgList)
  const onMarketBrowseRef = useRef(onMarketBrowse)
  const onSavedOrgsListRef = useRef(onSavedOrgsList)
  onRequestDataRef.current = onRequestData
  onRequestTalentsRef.current = onRequestTalents
  onRequestReorgListRef.current = onRequestReorgList
  onMarketBrowseRef.current = onMarketBrowse
  onSavedOrgsListRef.current = onSavedOrgsList

  useEffect(() => {
    onRequestDataRef.current()
    onRequestTalentsRef.current()
    onRequestReorgListRef.current()
    onMarketBrowseRef.current?.()
    onSavedOrgsListRef.current?.()
  }, [])

  useEffect(() => {
    if (!orgCreateResult || !orgCreateResult.ok) return
    setCreateOpen(false)
    setActiveTab('team')
    showToast(`Created ${orgCreateResult.organization_name || orgCreateResult.name} and saved automatically`)
  }, [orgCreateResult, showToast])

  // In org mode: show only user-owned roles. In company mode: show all roles read-only.
  const allRoles = data?.roles ?? []
  const displayRoles = useMemo(() => isCustomMode ? allRoles.filter(r => !r.is_builtin) : allRoles, [allRoles, isCustomMode])
  const displayEmployees = useMemo(() => data?.employees ?? [], [data?.employees])
  const runtimeView = useMemo(() => getRuntimeOrgView(data), [data])
  const activeAgents = useMemo(() => displayEmployees.filter(e => e.linked_agent_id), [displayEmployees])
  const configuredOrgName = data?.organization_name?.trim()
  const activeOrgLabel = configuredOrgName || humanizeOrgName(activeSavedOrg) || (isCustomMode ? 'Custom org' : 'Corporate company')
  const activeOrgId = (isCustomMode ? (data?.organization_id || activeSavedOrg) : 'corporate') || ''
  const architectureKindLabel = isCustomMode ? 'Saved org' : 'Corporate'
  const architectureStateLabel = isCustomMode
    ? activeSavedOrg ? 'Editable saved architecture' : 'Editable draft architecture'
    : 'Built-in read-only architecture'
  const runtimeStateLabel = runtimeView.frontier.status || runtimeView.projectRun?.status || runtimeView.projectRun?.lifecycle_status || 'ready'

  // Roles that already have at least one non-placeholder employee.
  const filledRoleIds = useMemo(
    () => {
      const ids = new Set<string>()
      for (const employee of displayEmployees) {
        if (employee.is_default_employee) continue
        const roleIds = employee.role_ids?.length ? employee.role_ids : [employee.role_id]
        for (const roleId of roleIds) {
          if (roleId) ids.add(roleId)
        }
      }
      return ids
    },
    [displayEmployees],
  )
  const vacantRoles = useMemo(() => displayRoles.filter(r => !filledRoleIds.has(r.role_id)), [displayRoles, filledRoleIds])

  const installedIds = useMemo(() => new Set((data?.installed_packages ?? []).map(p => p.package_id)), [data?.installed_packages])

  // When applying a preset, wait for org_version to change (every config.save() increments it)
  const orgVersion = data?.org_version ?? 0
  useEffect(() => {
    if (applyingPresetId && versionAtApply.current >= 0 && orgVersion !== versionAtApply.current) {
      setApplyingPresetId(null)
      versionAtApply.current = -1
      setActiveTab('team')
      showToast('Architecture applied successfully')
    }
  }, [orgVersion, applyingPresetId, showToast])

  const handleApplyPreset = (presetId: string, strategy: string) => {
    versionAtApply.current = orgVersion // snapshot current version
    setApplyingPresetId(presetId)
    onMarketApplyPreset?.(presetId, strategy)
  }

  const handleOrgSelection = (value: string) => {
    if (value === 'corporate') {
      onSelectCorporate?.()
      return
    }
    if (value.startsWith('org:')) {
      const orgName = value.slice(4)
      if (orgName) onSavedOrgLoad?.(orgName)
    }
  }

  if (!data) {
    return <div className="org-tab"><div className="org-loading">Loading organization data...</div></div>
  }

  const installedPackages = data.installed_packages ?? []
  const savedOrgOptions = savedOrgsList ?? []
  const selectedOrgValue = isCustomMode && activeSavedOrg ? `org:${activeSavedOrg}` : 'corporate'

  return (
    <div className="org-tab">
      <div className={`org-header${isCustomMode ? ' org-header--custom' : ' org-header--corporate'}`}>
        <div className="org-header-main">
          <div className="org-eyebrow">
            <span>Company</span>
            <span className="org-eyebrow-separator">/</span>
            <span>{architectureKindLabel}</span>
          </div>
          <div className="org-title-row">
            <h2 className="org-title">{activeOrgLabel}</h2>
            <span className="org-version-badge">v{data.org_version}</span>
            <span className={`org-state-badge${isCustomMode ? ' org-state-badge--editable' : ' org-state-badge--readonly'}`}>
              {architectureStateLabel}
            </span>
          </div>
          <div className="org-header-meta">
            <span className="org-meta-pill">{data.company_profile || (isCustomMode ? 'custom' : 'corporate')}</span>
            {activeOrgId && <code className="org-meta-code">{activeOrgId}</code>}
            <span className="org-meta-pill org-meta-pill--runtime">{runtimeStateLabel}</span>
            <span className="org-meta-pill org-meta-pill--saved">Auto-saved</span>
          </div>
        </div>

        <div className="org-control-panel">
          <label className="org-switcher">
            <span className="org-switcher-label">Organization</span>
            <span className="org-switcher-select-wrap">
              <select
                className="org-switcher-select"
                value={selectedOrgValue}
                onChange={e => handleOrgSelection(e.target.value)}
                onFocus={() => onSavedOrgsList?.()}
                onPointerDown={() => onSavedOrgsList?.()}
                aria-label="Organization"
              >
                <option value="corporate">Corporate</option>
                {savedOrgOptions.map(org => (
                  <option key={org.name} value={`org:${org.name}`}>
                    {(org.organization_name || org.name).trim() || org.name}
                  </option>
                ))}
              </select>
            </span>
          </label>
          <button type="button" className="org-create-trigger" onClick={() => setCreateOpen(true)}>
            <span className="org-create-trigger-icon" aria-hidden>+</span>
            New organization
          </button>
        </div>

        <div className="org-stats-strip">
          <span className="org-stat">
            <img src={STAT_ICON.agents} alt="" className="org-stat-icon" />
            <b>{displayRoles.length}</b> roles
          </span>
          <span className="org-stat">
            <img src={TAB_ICON.employees} alt="" className="org-stat-icon" />
            <b>{displayEmployees.length}</b> employees
          </span>
          <span className="org-stat">
            <img src={TAB_ICON.runtime} alt="" className="org-stat-icon" />
            <b>{runtimeView.runtimeTeams.length}</b> runtime teams
          </span>
          <span className="org-stat">
            <img src={STAT_ICON.active} alt="" className="org-stat-icon" />
            <b>{activeAgents.length}</b> active
          </span>
        </div>
      </div>

      <div className="org-subtabs">
        {([
          { id: 'team' as SubTab, icon: TAB_ICON.team, label: 'Team', count: displayRoles.length },
          { id: 'runtime' as SubTab, icon: TAB_ICON.runtime, label: 'Runtime', count: runtimeView.runtimeTeams.length },
          { id: 'architecture' as SubTab, icon: TAB_ICON.architecture, label: 'Architecture', count: marketPresets?.length ?? 0 },
          { id: 'employees' as SubTab, icon: TAB_ICON.employees, label: 'Employees', count: talents.length },
        ]).map(tab => (
          <button key={tab.id}
            className={`org-subtab${activeTab === tab.id ? ' org-subtab--active' : ''}`}
            onClick={() => switchTab(tab.id)}>
            <img src={tab.icon} alt="" className="org-subtab-icon" />
            <span className="org-subtab-label">{tab.label}</span>
            <span className="org-subtab-count">{tab.count}</span>
          </button>
        ))}
      </div>

      {/* ── Tab content ─────────────────────────────────── */}
      {/* Toast notification */}
      {toast && (
        <div className={`org-toast org-toast--${toast.type}`} onClick={() => setToast(null)}>
          {toast.msg}
        </div>
      )}

      <div className="org-tab-content">

        {/* Team tab */}
        {activeTab === 'team' && (
          <TeamView
            roles={displayRoles}
            employees={displayEmployees}
            sessionRecruitmentByRole={sessionRecruitmentByRole}
            isCustomMode={isCustomMode}
            onAddRole={onAddRole ?? (() => {})}
            onBulkAddRoles={onBulkAddRoles}
            onUpdateRole={onUpdateRole ?? (() => {})}
            onDeleteRole={onDeleteRole ?? (() => {})}
            onExport={onMarketExport ?? (() => {})}
            onImportEmployee={onImportEmployee}
            onResetArchitecture={onResetArchitecture}
            onSwitchToTab={(target) => setActiveTab(target)}
            savedOrgsList={savedOrgsList}
            activeSavedOrg={activeSavedOrg ?? null}
            currentOrgVersion={data?.org_version ?? 0}
            versionAtLoad={activeSavedOrgVersionAtLoad ?? null}
            onSavedOrgsList={onSavedOrgsList}
            onSavedOrgSaveAs={onSavedOrgSaveAs}
            onSavedOrgLoad={onSavedOrgLoad}
            onSavedOrgDelete={onSavedOrgDelete}
          />
        )}

        {/* Runtime tab */}
        {activeTab === 'runtime' && (
          <DelegationStrategyPanel
            roles={displayRoles}
            runtimeTeams={runtimeView.runtimeTeams}
            runtimeSeats={runtimeView.runtimeSeats}
            workItems={runtimeView.workItems}
            frontier={runtimeView.frontier}
            companyProfile={data.company_profile}
            runtimePolicy={data.runtime_policy}
            finalDeciderRoleId={data.final_decider_role_id}
            topLevelRoleIds={data.top_level_role_ids}
            readOnly={!isCustomMode}
            onUpdateOrgStrategy={onUpdateOrgStrategy}
            onUpdateRuntimePolicy={onUpdateRuntimePolicy}
          />
        )}

        {/* Architecture tab */}
        {activeTab === 'architecture' && (
          <>
            <ArchitectureMarketplace
              presets={marketPresets ?? []}
              installedIds={installedIds}
              previewData={marketPreviewData ?? null}
              applyingPresetId={applyingPresetId}
              readOnly={!isCustomMode}
              onPreview={onMarketPreview ?? (() => {})}
              onApplyPreset={handleApplyPreset}
              onClearPreview={onMarketClearPreview ?? (() => {})}
              installedPackages={installedPackages}
              channels={data.channels}
              reorgProposals={reorgProposals}
              isCustomMode={!!isCustomMode}
              onReorgDecide={onReorgDecide}
              onMarketInstall={(p, s) => onMarketInstall?.(p, s)}
              onMarketUninstall={(id) => onMarketUninstall?.(id)}
            />
            {isCustomMode && (
              <ConfigImportExportPanel
                onExport={onConfigExport ?? (() => {})}
                onImport={onConfigImport ?? (() => {})}
                configExportYaml={configExportYaml ?? null}
                importPreview={configImportPreview ?? null}
                importError={configImportError ?? null}
              />
            )}
          </>
        )}

        {/* Employees tab */}
        {activeTab === 'employees' && (
          <EmployeesMarketplace
            templates={talents}
            vacantRoles={vacantRoles}
            hiringTemplateId={hiringTemplateId ?? null}
            readOnly={!isCustomMode}
            onHireTalent={onHireTalent}
          />
        )}
      </div>
      <OrgCreateModal
        open={createOpen}
        pending={orgCreatePending}
        result={orgCreateResult ?? null}
        onClose={() => setCreateOpen(false)}
        onCreate={(organizationName, members) => onSavedOrgCreate?.(organizationName, members)}
      />
    </div>
  )
}
