import { useState, useEffect } from 'react';
import { Dropdown } from 'primereact/dropdown';
import { Button } from 'primereact/button';
import { Tree } from 'primereact/tree';
import type { TreeNode } from 'primereact/treenode';
import { Card } from 'primereact/card';
import { Tag } from 'primereact/tag';
import { ProgressSpinner } from 'primereact/progressspinner';
import BasePageHeader from '@/core/components/BasePageHeader';
import WbsUploadDialog from '../components/WbsUploadDialog';
import { wbsService } from '../wbs.service';
import { projectService } from '@/modules/project/project.service';
import type { WbsVersion, WbsNode } from '../wbs.types';
import { toArray } from '@/core/api/utils';

function nodesToTreeNodes(nodes: WbsNode[]): TreeNode[] {
  return nodes.map((n) => ({
    key: String(n.id),
    label: `${n.code} - ${n.name}`,
    children: n.children ? nodesToTreeNodes(n.children) : [],
  }));
}

export default function WbsTreeView() {
  const [projects, setProjects] = useState<{ id: number; name: string; code: string }[]>([]);
  const [selectedProjectId, setSelectedProjectId] = useState<number | null>(null);
  const [versions, setVersions] = useState<WbsVersion[]>([]);
  const [selectedVersion, setSelectedVersion] = useState<number | null>(null);
  const [treeNodes, setTreeNodes] = useState<TreeNode[]>([]);
  const [loading, setLoading] = useState(false);
  const [uploadVisible, setUploadVisible] = useState(false);

  useEffect(() => {
    projectService.getAll()
      .then(({ data }) => setProjects(toArray<{ id: number; name: string; code: string }>(data)))
      .catch(() => setProjects([]));
  }, []);

  useEffect(() => {
    if (!selectedProjectId) { setVersions([]); return; }
    wbsService.getVersions(selectedProjectId)
      .then(({ data }) => setVersions(toArray<WbsVersion>(data)))
      .catch(() => setVersions([]));
  }, [selectedProjectId]);

  useEffect(() => {
    if (!selectedProjectId || !selectedVersion) { setTreeNodes([]); return; }
    setLoading(true);
    wbsService.getVersionNodes(selectedProjectId, selectedVersion)
      .then(({ data }) => setTreeNodes(nodesToTreeNodes(toArray<WbsNode>(data))))
      .catch(() => setTreeNodes([]))
      .finally(() => setLoading(false));
  }, [selectedProjectId, selectedVersion]);

  async function handleUpload(file: File, effectiveDate: string) {
    if (!selectedProjectId) return;
    await wbsService.upload(selectedProjectId, file, effectiveDate);
    setUploadVisible(false);
    const { data } = await wbsService.getVersions(selectedProjectId);
    setVersions(toArray<WbsVersion>(data));
  }

  return (
    <div>
      <BasePageHeader title="WBS 관리" actions={<Button label="P6 업로드" icon="pi pi-upload" size="small" disabled={!selectedProjectId} onClick={() => setUploadVisible(true)} />} />

      <div style={{ display: 'flex', gap: '0.5rem', marginBottom: '1rem', flexWrap: 'wrap' }}>
        <Dropdown value={selectedProjectId} options={projects.map((p) => ({ label: `${p.code} - ${p.name}`, value: p.id }))} onChange={(e) => { setSelectedProjectId(e.value); setSelectedVersion(null); }} placeholder="프로젝트 선택" style={{ minWidth: '250px' }} />
        <Dropdown value={selectedVersion} options={versions.map((v) => ({ label: `v${v.versionNumber} (${v.effectiveDate})`, value: v.versionNumber }))} onChange={(e) => setSelectedVersion(e.value)} placeholder="버전 선택" disabled={!selectedProjectId} />
        {versions.find((v) => v.versionNumber === selectedVersion) && (
          <Tag value={versions.find((v) => v.versionNumber === selectedVersion)?.status ?? ''} severity={versions.find((v) => v.versionNumber === selectedVersion)?.status === 'ACTIVE' ? 'success' : 'secondary'} />
        )}
      </div>

      <Card>
        {loading ? (
          <div style={{ display: 'flex', justifyContent: 'center', padding: '2rem' }}><ProgressSpinner /></div>
        ) : treeNodes.length > 0 ? (
          <Tree value={treeNodes} />
        ) : (
          <p style={{ textAlign: 'center', color: 'var(--p-text-muted-color)', padding: '2rem' }}>프로젝트와 버전을 선택하세요.</p>
        )}
      </Card>

      <WbsUploadDialog visible={uploadVisible} onHide={() => setUploadVisible(false)} onUpload={handleUpload} />
    </div>
  );
}
