import { useEffect, useState } from 'react'
import {
  getStageHistory,
  updateAssignments,
  updateStage,
  type Contact,
  type ContactCategory,
  type Org,
} from '../api/client'
import { STAGE_LABELS, stageLabel } from '../stages'
import ChannelFiles from './ChannelFiles'
import ChannelPosts from './ChannelPosts'
import ContactPickerModal from './ContactPickerModal'
import StatusBadge from './StatusBadge'
import Timeline from './Timeline'
import WorkMemos from './WorkMemos'

// 기관관리 상세 화면. 3단계 대시보드 시안의 "기관관리" 레이아웃을 따른다.
// 웹 DB에 있는 것(연번·기관명·담당자 3종·채널·진행단계)만 실데이터고,
// 통계/일부 탭 내용은 아직 백엔드가 없어 시안과 같은 골격에 "추후 연동" 자리만 잡아 둔다.

const TABS = ['채팅', '자료', '권리확인', '권리처리', 'RE', '타임라인', '업무메모']

// 담당 변호사 변경은 카드의 [생성/변경] 버튼으로 대체되어 목록에서 뺐다.
// 진행단계 변경은 업무단계 현황 스트립 + 이 버튼의 모달로 실제 동작한다.
const DISABLED_ACTIONS = ['자료 업로드', '최초 게시글 보기', '보고서 관리']

// 카드에서 담당자를 지정/변경할 때 쓰는 역할 정의 (채널관리의 배정과 같은 API를 쓴다)
const CARD_ROLES: Record<
  'applicant' | 'mj' | 'itn' | 'lawyer',
  { category: ContactCategory; pickerTitle: string }
> = {
  applicant: { category: 'APPLICANT', pickerTitle: '신청기관 담당자 선택' },
  mj: { category: 'MJ', pickerTitle: '문정원 담당자 선택' },
  itn: { category: 'ITN', pickerTitle: '아이티앤 담당자 선택' },
  lawyer: { category: 'LAWYER', pickerTitle: '담당 변호사 선택' },
}

// Mattermost 웹 주소. 채널 화면은 팀명 + 채널 내부명으로 열린다.
// 내부명 규칙은 백엔드 ChannelNaming.java가 정본이며 여기서는 열람 링크용으로만 복제한다.
// 기관 코드({연번1}_{연번2})가 하위기관까지 구분하므로 기관명에 따른 별도 특례는 없다.
const MATTERMOST_BASE = 'https://hub.iten.co.kr/itn-hub/channels/'

function mattermostChannelUrl(org: Org): string {
  const slug = org.orgNo.trim().toLowerCase().replace(/_/g, '-').replace(/ /g, '-')
  return MATTERMOST_BASE + `org-${slug}-mj`
}

const stageDateFormatter = new Intl.DateTimeFormat('ko-KR', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
})

/** 2026. 07. 24. → 2026-07-24 */
function formatStageDate(ms: number): string {
  return stageDateFormatter.format(new Date(ms)).replace(/\. ?/g, '-').replace(/-$/, '')
}

function Field({ label, value }: { label: string; value: string | null }) {
  return (
    <div className="flex gap-3 text-sm">
      <span className="w-14 shrink-0 text-gray-400">{label}</span>
      <span className={value ? 'font-medium text-gray-900' : 'text-gray-300'}>
        {value ?? '-'}
      </span>
    </div>
  )
}

function ContactCard({
  title,
  fields,
  assigned,
  busy,
  onEdit,
}: {
  title: string
  fields: { label: string; value: string | null }[]
  assigned: boolean
  busy: boolean
  onEdit: () => void
}) {
  return (
    <section className="rounded-lg border border-gray-200 p-4">
      <div className="flex items-center justify-between">
        <h2 className="text-sm font-semibold">{title}</h2>
        <button
          type="button"
          disabled={busy}
          aria-label={`${title} ${assigned ? '변경' : '생성'}`}
          onClick={onEdit}
          className="rounded-md border border-gray-300 px-2 py-0.5 text-xs text-gray-600 hover:bg-gray-50 disabled:opacity-40"
        >
          {assigned ? '변경' : '생성'}
        </button>
      </div>
      <div className="mt-3 space-y-1.5">
        {fields.map((f) => (
          <Field key={f.label} label={f.label} value={f.value} />
        ))}
      </div>
    </section>
  )
}

export default function OrgOverview({
  org,
  onChanged,
}: {
  org: Org
  onChanged?: () => void
}) {
  const [activeTab, setActiveTab] = useState(TABS[0])
  const [pickerRole, setPickerRole] = useState<'applicant' | 'mj' | 'itn' | 'lawyer' | null>(null)
  const [assignBusy, setAssignBusy] = useState(false)
  const [assignError, setAssignError] = useState<string | null>(null)

  const [stageBusy, setStageBusy] = useState(false)
  const [stageError, setStageError] = useState<string | null>(null)
  const [stagePickerOpen, setStagePickerOpen] = useState(false)
  // 단계별로 '그 단계에 들어간 날짜'(가장 최근 이력)를 찍기 위한 조회 결과
  const [stageDates, setStageDates] = useState<Record<number, number>>({})

  useEffect(() => {
    let cancelled = false
    getStageHistory(org.id)
      .then((rows) => {
        if (cancelled) {
          return
        }
        // 최신순으로 오므로, 단계별 첫 등장( = 가장 최근 도달 시각)만 채택한다
        const dates: Record<number, number> = {}
        for (const row of rows) {
          if (!(row.stage in dates)) {
            dates[row.stage] = row.changedAt
          }
        }
        setStageDates(dates)
      })
      .catch(() => {
        /* 날짜는 장식이다 - 조회 실패로 화면을 깨지 않는다 */
      })
    return () => {
      cancelled = true
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [org.id, org.stage])

  async function assign(role: 'applicant' | 'mj' | 'itn' | 'lawyer', contact: Contact) {
    setPickerRole(null)
    setAssignError(null)
    setAssignBusy(true)
    try {
      await updateAssignments(org.id, {
        applicantContactId: role === 'applicant' ? contact.id : (org.applicant?.id ?? null),
        mjContactId: role === 'mj' ? contact.id : (org.mj?.id ?? null),
        itnContactId: role === 'itn' ? contact.id : (org.itn?.id ?? null),
        lawyerContactId: role === 'lawyer' ? contact.id : (org.lawyer?.id ?? null),
        lawyerAssignedDate: org.lawyerAssignedDate ?? null,
      })
      onChanged?.()
    } catch (e) {
      setAssignError(e instanceof Error ? e.message : '담당자 지정에 실패했습니다.')
    } finally {
      setAssignBusy(false)
    }
  }

  /** 실제로 진행단계를 바꾸는 공통 경로. 스트립의 "다음 단계로" 클릭과 [진행단계 변경]
   * 모달의 단계 선택이 모두 여기를 거친다. */
  async function changeStage(next: number) {
    setStageError(null)
    setStageBusy(true)
    try {
      await updateStage(org.id, next)
      onChanged?.()
    } catch (e) {
      setStageError(e instanceof Error ? e.message : '진행단계 변경에 실패했습니다.')
    } finally {
      setStageBusy(false)
    }
  }

  /** 업무단계 현황 스트립에서 "현재 단계"를 클릭했을 때만 호출된다 - 다음 단계로 1칸 전진. */
  async function advanceStage() {
    if (org.stage === null || org.stage >= 12 || stageBusy) {
      return
    }
    const next = org.stage + 1
    if (!window.confirm(`다음 단계 "${next}. ${stageLabel(next)}"(으)로 진행할까요?`)) {
      return
    }
    await changeStage(next)
  }

  async function pickStage(next: number) {
    if (!window.confirm(`"${next}. ${stageLabel(next)}"(으)로 진행단계를 변경할까요?`)) {
      return
    }
    setStagePickerOpen(false)
    await changeStage(next)
  }

  return (
    <div className="p-6">
      <div className="rounded-xl border border-gray-200 bg-white p-6">
        {/* 헤더 */}
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div className="flex items-center gap-3">
            <h1 className="text-lg font-bold">
              {org.orgNo}_{org.orgName}
            </h1>
            <StatusBadge status={org.status} />
          </div>

          <div className="flex flex-wrap gap-2">
            <button
              type="button"
              disabled={stageBusy}
              onClick={() => setStagePickerOpen(true)}
              className="rounded-md border border-gray-300 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50 disabled:opacity-50"
            >
              진행단계 변경
            </button>
            {DISABLED_ACTIONS.map((label) => (
              <button
                key={label}
                type="button"
                disabled
                title="준비 중"
                className="cursor-not-allowed rounded-md border border-gray-200 px-3 py-1.5 text-sm text-gray-300"
              >
                {label}
              </button>
            ))}
            {org.channelIdMj ? (
              <a
                href={mattermostChannelUrl(org)}
                target="_blank"
                rel="noreferrer"
                className="rounded-md border border-gray-300 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-50"
              >
                Mattermost 열기
              </a>
            ) : (
              <button
                type="button"
                disabled
                title="채널이 아직 없습니다"
                className="cursor-not-allowed rounded-md border border-gray-200 px-3 py-1.5 text-sm text-gray-300"
              >
                Mattermost 열기
              </button>
            )}
          </div>
        </div>

        {/* 담당자 카드 4개 (신청기관/문정원/아이티앤/변호사). 담당자 정보 입력은 담당자관리에서만 하고,
            여기서는 [생성/변경]으로 이미 등록된 담당자를 골라 배정만 한다(채널관리와 같은 API). */}
        <div className="mt-5 grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
          <ContactCard
            title="신청기관 담당자"
            assigned={org.applicant !== null}
            busy={assignBusy}
            onEdit={() => setPickerRole('applicant')}
            fields={[
              { label: '부서', value: org.applicant?.deptName ?? null },
              {
                label: '담당자',
                value: org.applicant
                  ? org.applicant.title
                    ? `${org.applicant.name} ${org.applicant.title}`
                    : org.applicant.name
                  : null,
              },
              { label: '연락처', value: org.applicant?.phone ?? null },
              { label: '이메일', value: org.applicant?.email ?? null },
            ]}
          />
          <ContactCard
            title="문정원 담당자"
            assigned={org.mj !== null}
            busy={assignBusy}
            onEdit={() => setPickerRole('mj')}
            fields={[
              { label: '부서', value: org.mj?.deptName ?? null },
              { label: '담당자', value: org.mj?.name ?? null },
              { label: '연락처', value: org.mj?.phone ?? null },
              { label: '이메일', value: org.mj?.email ?? null },
            ]}
          />
          <ContactCard
            title="아이티앤 담당자"
            assigned={org.itn !== null}
            busy={assignBusy}
            onEdit={() => setPickerRole('itn')}
            fields={[
              { label: '부서', value: org.itn?.deptName ?? null },
              { label: '담당자', value: org.itn?.name ?? null },
              { label: '연락처', value: org.itn?.phone ?? null },
              { label: '이메일', value: org.itn?.email ?? null },
            ]}
          />
          <ContactCard
            title="담당 변호사"
            assigned={org.lawyer !== null}
            busy={assignBusy}
            onEdit={() => setPickerRole('lawyer')}
            fields={[
              { label: '성명', value: org.lawyer?.name ?? null },
              { label: '연락처', value: org.lawyer?.phone ?? null },
              { label: '이메일', value: org.lawyer?.email ?? null },
              { label: '배정일', value: org.lawyerAssignedDate },
            ]}
          />
        </div>

        {assignError && <p className="mt-2 text-sm text-red-600">{assignError}</p>}

        {pickerRole && (
          <ContactPickerModal
            category={CARD_ROLES[pickerRole].category}
            title={CARD_ROLES[pickerRole].pickerTitle}
            onSelect={(contact) => void assign(pickerRole, contact)}
            onClose={() => setPickerRole(null)}
          />
        )}

        {/* 업무단계 현황: 완료된 단계는 초록 체크, 현재 단계는 파란 강조 + 클릭 시 다음 단계로
            전진(확인 후), 그 뒤 단계는 회색 그대로. 채널 생성 전(stage === null)에는 전부 회색이다. */}
        <section className="mt-5">
          <h2 className="text-sm font-semibold">업무단계 현황</h2>
          <ol className="mt-3 flex gap-2 overflow-x-auto pb-2">
            {STAGE_LABELS.map((step, i) => {
              const n = i + 1
              const isDone = org.stage !== null && n < org.stage
              const isCurrent = org.stage !== null && n === org.stage
              const clickable = isCurrent && n < 12

              return (
                <li key={step} className="shrink-0">
                  <button
                    type="button"
                    disabled={!clickable || stageBusy}
                    title={isCurrent && n >= 12 ? '마지막 단계입니다' : undefined}
                    onClick={() => {
                      if (isCurrent) {
                        void advanceStage()
                      }
                    }}
                    className={`flex w-24 flex-col items-center gap-1 rounded-lg border px-2 py-3 text-center ${
                      isDone
                        ? 'border-emerald-200 bg-emerald-50'
                        : isCurrent
                          ? 'border-blue-400 bg-blue-50'
                          : 'border-gray-200'
                    } ${clickable ? 'cursor-pointer hover:bg-blue-100' : 'cursor-default disabled:opacity-100'}`}
                  >
                    <span
                      className={`flex h-6 w-6 items-center justify-center rounded-full border text-xs ${
                        isDone
                          ? 'border-emerald-500 bg-emerald-500 text-white'
                          : isCurrent
                            ? 'border-blue-600 bg-blue-600 text-white'
                            : 'border-gray-300 text-gray-500'
                      }`}
                    >
                      {isDone ? '✓' : n}
                    </span>
                    <span
                      className={`text-[11px] leading-tight ${
                        isDone ? 'text-emerald-700' : isCurrent ? 'font-semibold text-blue-700' : 'text-gray-600'
                      }`}
                    >
                      {step}
                    </span>
                    {isCurrent ? (
                      <>
                        <span className="text-[11px] font-semibold text-blue-600">진행중</span>
                        <span className="text-[10px] text-blue-500">
                          {stageDates[n] ? formatStageDate(stageDates[n]) : ''}
                        </span>
                      </>
                    ) : isDone && stageDates[n] ? (
                      <span className="text-[10px] text-emerald-600">
                        {formatStageDate(stageDates[n])}
                      </span>
                    ) : (
                      <span className="text-[11px] text-gray-300">-</span>
                    )}
                  </button>
                </li>
              )
            })}
          </ol>
          {org.stage === null && (
            <p className="mt-1 text-xs text-gray-400">채널 생성 시 신청 단계가 시작됩니다</p>
          )}
          {stageError && <p className="mt-1 text-xs text-red-600">{stageError}</p>}
        </section>

        {/* 통계 4칸 */}
        <div className="mt-4 grid grid-cols-2 gap-3 lg:grid-cols-4">
          {[
            ['사전검토', '검토 대상'],
            ['권리확인', '완료 / 전체'],
            ['권리처리', '완료 / 전체'],
            ['RE', '확인·처리 합계'],
          ].map(([title, caption]) => (
            <div key={title} className="rounded-lg border border-gray-200 p-4">
              <p className="text-xs text-gray-400">{title}</p>
              <p className="mt-1 text-sm font-semibold">
                {caption} <span className="ml-1 text-lg text-gray-300">-</span>
              </p>
            </div>
          ))}
        </div>

        {/* 탭 */}
        <div className="mt-6 border-b border-gray-200">
          <nav className="flex gap-1" aria-label="기관 상세 탭">
            {TABS.map((tab) => (
              <button
                key={tab}
                type="button"
                onClick={() => setActiveTab(tab)}
                aria-current={activeTab === tab ? 'true' : undefined}
                className={`border-b-2 px-4 py-2 text-sm ${
                  activeTab === tab
                    ? 'border-blue-600 font-semibold text-blue-600'
                    : 'border-transparent text-gray-500 hover:text-gray-700'
                }`}
              >
                {tab}
              </button>
            ))}
          </nav>
        </div>

        {activeTab === '채팅' ? (
          <div className="mt-4 rounded-lg border border-gray-200">
            <ChannelPosts key={org.id} org={org} />
          </div>
        ) : activeTab === '자료' ? (
          <div className="mt-4 rounded-lg border border-gray-200">
            <ChannelFiles key={org.id} org={org} />
          </div>
        ) : activeTab === '업무메모' ? (
          <div className="mt-4 rounded-lg border border-gray-200">
            <WorkMemos key={org.id} org={org} />
          </div>
        ) : activeTab === '타임라인' ? (
          <div className="mt-4 rounded-lg border border-gray-200">
            <Timeline key={org.id} org={org} />
          </div>
        ) : (
          <div className="mt-4 rounded-lg border border-dashed border-gray-200 p-10 text-center text-sm text-gray-400">
            {activeTab} 상세 화면은 추후 확정
          </div>
        )}
      </div>

      {stagePickerOpen && (
        <StagePickerModal
          currentStage={org.stage}
          busy={stageBusy}
          onPick={(n) => void pickStage(n)}
          onClose={() => setStagePickerOpen(false)}
        />
      )}
    </div>
  )
}

/** [진행단계 변경] 버튼이 여는 모달. 12개 단계 중 하나를 골라 바로 그 단계로 변경한다
 * (현재 단계는 굵게 표시). ContactPickerModal과 같은 오버레이/닫기 규칙을 따른다. */
function StagePickerModal({
  currentStage,
  busy,
  onPick,
  onClose,
}: {
  currentStage: number | null
  busy: boolean
  onPick: (stage: number) => void
  onClose: () => void
}) {
  return (
    <div className="fixed inset-0 flex items-center justify-center bg-black/30">
      <div className="w-96 rounded-lg bg-white p-5">
        <div className="flex items-center justify-between">
          <h2 className="text-base font-semibold">진행단계 변경</h2>
          <button
            type="button"
            onClick={onClose}
            aria-label="닫기"
            className="rounded-md p-1 text-gray-400 hover:bg-gray-100"
          >
            ✕
          </button>
        </div>

        <ul className="mt-3 max-h-80 space-y-1 overflow-y-auto">
          {STAGE_LABELS.map((label, i) => {
            const n = i + 1
            const isCurrent = currentStage === n
            return (
              <li key={label}>
                <button
                  type="button"
                  disabled={busy}
                  onClick={() => onPick(n)}
                  className={`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-gray-50 disabled:opacity-50 ${
                    isCurrent ? 'font-semibold text-blue-700' : 'text-gray-700'
                  }`}
                >
                  <span className="w-5 shrink-0 text-xs text-gray-400">{n}</span>
                  <span>{label}</span>
                  {isCurrent && <span className="ml-auto text-xs text-blue-500">현재</span>}
                </button>
              </li>
            )
          })}
        </ul>
      </div>
    </div>
  )
}
