/*
 * SCR-26 공사/장치 옥션 목록·개설 [M15]. 실 API 전환.
 * 정본: GET /api/auctions (AuctionSummary[]) · POST /api/auctions (개설 — 발주자 권한, 서버 검증).
 * 대상: 참가업체·주최자(발주). 좌 옥션 카드 목록 + 우 옥션 개설 패널.
 * 보안: 개설·초대는 등록업체 게이트가 서버에서 강제(미등록 초대 id 는 서버가 필터). 발주 권한 없으면 403.
 */
import { useMemo, useState, type ReactNode } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { Button } from '../../components/ui/Button';
import { DdayChip } from '../../components/ui/Badge';
import { EmptyState, ErrorState, Skeleton } from '../../components/ui/States';
import {
  IconPlus,
  IconDocument,
  IconFloorplan,
  IconImage,
  IconSettings,
} from '../../components/ui/icons';
import {
  MATERIAL_LABEL,
  auctionApi,
  formatWon,
  type AuctionStatus,
  type AuctionSummary,
  type AwardCriteria,
  type AuctionType,
  type MaterialKind,
} from './auctionApi';
import { errMessage, useToast } from './aucShared';
import './auction.css';

type TabKey = 'live' | 'closed' | 'mine';
const TABS: { key: TabKey; label: string }[] = [
  { key: 'live', label: '진행중' },
  { key: 'closed', label: '마감' },
  { key: 'mine', label: '역경매' },
];

const CATEGORIES = ['전시디자인설치', '구조물 임대', '전기/조명', '영상/음향', '네트워크'];
const MATERIAL_KINDS: MaterialKind[] = ['layout', 'design', 'boq', 'aiimage'];

const MAT_ICON: Record<MaterialKind, ReactNode> = {
  layout: <IconFloorplan size={16} />,
  design: <IconSettings size={16} />,
  boq: <IconDocument size={16} />,
  aiimage: <IconImage size={16} />,
};

export function AuctionListPage() {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const { show, node: toast } = useToast();
  const [tab, setTab] = useState<TabKey>('live');

  const q = useQuery({
    queryKey: ['auctions'],
    queryFn: () => auctionApi.list(),
    retry: false,
    refetchInterval: 15000,
  });
  const auctions = q.data ?? [];

  // 개설 폼 상태
  const eventIds = useMemo(
    () => Array.from(new Set(auctions.map((a) => a.eventId))).filter(Boolean),
    [auctions],
  );
  const [eventId, setEventId] = useState('');
  const [title, setTitle] = useState('');
  const [category, setCategory] = useState(CATEGORIES[0]);
  const [type, setType] = useState<AuctionType>('역경매');
  const [criteria, setCriteria] = useState<AwardCriteria>('comprehensive');
  const [weights, setWeights] = useState({ price: 60, reputation: 25, delivery: 15 });
  const [round, setRound] = useState(1);
  const [deadline, setDeadline] = useState('');
  const [materials, setMaterials] = useState<Set<MaterialKind>>(new Set(MATERIAL_KINDS));

  const effectiveEventId = eventId || eventIds[0] || '';

  const createM = useMutation({
    mutationFn: () =>
      auctionApi.create({
        eventId: effectiveEventId,
        title: title.trim(),
        category,
        type,
        awardCriteria: criteria,
        weights,
        round,
        deadline,
        materials: Array.from(materials),
        invitedCompanyIds: [], // 공개 옥션(등록업체 응찰). 초대 세분은 후속.
      }),
    onSuccess: () => {
      show('옥션 공고를 게시했습니다.');
      setTitle('');
      setDeadline('');
      qc.invalidateQueries({ queryKey: ['auctions'] });
    },
    onError: (e) => show(errMessage(e)),
  });

  const visible = useMemo(() => {
    if (tab === 'closed') return auctions.filter((a) => a.status !== '진행중');
    if (tab === 'mine') return auctions.filter((a) => a.type === '역경매');
    return auctions.filter((a) => a.status === '진행중');
  }, [tab, auctions]);

  function submitCreate() {
    if (!effectiveEventId) return show('행사를 선택해 주세요.');
    if (!title.trim()) return show('공고명을 입력해 주세요.');
    if (!deadline) return show('마감 기한을 선택해 주세요.');
    createM.mutate();
  }

  return (
    <div className="kx-page kx-auc">
      <header className="kx-auc__head">
        <div>
          <h1 className="kx-auc__title">공사·장치 옥션</h1>
          <p className="kx-auc__subtitle">AI 설계자료(M2~M5) 기반 역경매 · 등록업체 응찰</p>
        </div>
        <div className="kx-auc__head-actions">
          <div className="kx-seg" role="tablist" aria-label="옥션 필터">
            {TABS.map((t) => (
              <button
                key={t.key}
                role="tab"
                aria-selected={tab === t.key}
                className={`kx-seg__btn ${tab === t.key ? 'is-active' : ''}`}
                onClick={() => setTab(t.key)}
              >
                {t.label}
              </button>
            ))}
          </div>
        </div>
      </header>

      <div className="kx-auc__split">
        {/* 좌 — 옥션 카드 목록 */}
        <section className="kx-auc__list" aria-label="옥션 목록">
          {q.isLoading && (
            <>
              <Skeleton height={168} radius={16} />
              <Skeleton height={168} radius={16} />
            </>
          )}
          {q.isError && !q.isLoading && (
            <ErrorState message="옥션 목록을 불러오지 못했습니다." onRetry={() => q.refetch()} />
          )}
          {!q.isLoading && !q.isError && visible.length === 0 && (
            <EmptyState
              title="해당 조건의 옥션이 없습니다"
              description="새로운 시공 옥션을 개설해 협력사를 모집하세요."
            />
          )}
          {!q.isLoading &&
            !q.isError &&
            visible.map((a) => (
              <AuctionCard key={a.id} auction={a} onOpen={() => navigate(`/auctions/${a.id}`)} />
            ))}
        </section>

        {/* 우 — 옥션 개설 패널 */}
        <aside className="kx-auc-open" aria-label="옥션 개설">
          <div className="kx-auc-open__head">
            <h2>
              <IconPlus size={18} /> 옥션 개설
            </h2>
            <p>새 시공 옥션을 공고하고 등록 협력사를 모집합니다.</p>
          </div>
          <div className="kx-auc-open__body">
            <div className="kx-field">
              <label className="kx-field__label" htmlFor="auc-event">
                행사 선택
              </label>
              <select
                id="auc-event"
                className="kx-input"
                value={effectiveEventId}
                onChange={(e) => setEventId(e.target.value)}
              >
                {eventIds.length === 0 && <option value="">행사 없음</option>}
                {eventIds.map((eid) => (
                  <option key={eid} value={eid}>
                    {eid}
                  </option>
                ))}
              </select>
            </div>

            <div className="kx-field">
              <label className="kx-field__label" htmlFor="auc-title">
                공고명
              </label>
              <input
                id="auc-title"
                className="kx-input"
                type="text"
                value={title}
                placeholder="예: A-102 독립부스 시공"
                onChange={(e) => setTitle(e.target.value)}
              />
            </div>

            <div className="kx-grid-2">
              <div className="kx-field">
                <label className="kx-field__label" htmlFor="auc-cat">
                  카테고리
                </label>
                <select
                  id="auc-cat"
                  className="kx-input"
                  value={category}
                  onChange={(e) => setCategory(e.target.value)}
                >
                  {CATEGORIES.map((c) => (
                    <option key={c}>{c}</option>
                  ))}
                </select>
              </div>
              <div className="kx-field">
                <span className="kx-field__label">옥션 유형</span>
                <div className="kx-seg" role="tablist" aria-label="옥션 유형">
                  <button
                    role="tab"
                    aria-selected={type === '역경매'}
                    className={`kx-seg__btn ${type === '역경매' ? 'is-active' : ''}`}
                    onClick={() => setType('역경매')}
                  >
                    역경매
                  </button>
                  <button
                    role="tab"
                    aria-selected={type === 'RFQ'}
                    className={`kx-seg__btn ${type === 'RFQ' ? 'is-active' : ''}`}
                    onClick={() => setType('RFQ')}
                  >
                    RFQ
                  </button>
                </div>
              </div>
            </div>

            <div className="kx-field">
              <span className="kx-field__label">낙찰 기준 (Award Criteria)</span>
              <div className="kx-seg" role="tablist" aria-label="낙찰 기준">
                <button
                  role="tab"
                  aria-selected={criteria === 'lowest'}
                  className={`kx-seg__btn ${criteria === 'lowest' ? 'is-active' : ''}`}
                  onClick={() => setCriteria('lowest')}
                >
                  최저가
                </button>
                <button
                  role="tab"
                  aria-selected={criteria === 'comprehensive'}
                  className={`kx-seg__btn ${criteria === 'comprehensive' ? 'is-active' : ''}`}
                  onClick={() => setCriteria('comprehensive')}
                >
                  종합평가
                </button>
              </div>
            </div>

            {criteria === 'comprehensive' && (
              <div className="kx-weights" aria-label="종합평가 가중치">
                <WeightSlider
                  label="가격 평가"
                  value={weights.price}
                  onChange={(v) => setWeights((w) => ({ ...w, price: v }))}
                />
                <WeightSlider
                  label="평판/경력"
                  value={weights.reputation}
                  onChange={(v) => setWeights((w) => ({ ...w, reputation: v }))}
                />
                <WeightSlider
                  label="납기/준수"
                  value={weights.delivery}
                  onChange={(v) => setWeights((w) => ({ ...w, delivery: v }))}
                />
              </div>
            )}

            <div className="kx-grid-2">
              <div className="kx-field">
                <label className="kx-field__label" htmlFor="auc-round">
                  차수 (Round)
                </label>
                <input
                  id="auc-round"
                  className="kx-input"
                  type="number"
                  min={1}
                  value={round}
                  onChange={(e) => setRound(Math.max(1, Number(e.target.value) || 1))}
                />
              </div>
              <div className="kx-field">
                <label className="kx-field__label" htmlFor="auc-deadline">
                  마감 기한
                </label>
                <input
                  id="auc-deadline"
                  className="kx-input"
                  type="date"
                  value={deadline}
                  onChange={(e) => setDeadline(e.target.value)}
                />
              </div>
            </div>

            <div className="kx-field">
              <span className="kx-field__label">설계 데이터 연동 (M2~M5)</span>
              <div className="kx-invite" role="group" aria-label="첨부 자료">
                {MATERIAL_KINDS.map((m) => (
                  <label key={m} className="kx-invite__row">
                    <span>{MATERIAL_LABEL[m]}</span>
                    <input
                      type="checkbox"
                      checked={materials.has(m)}
                      onChange={(e) =>
                        setMaterials((prev) => {
                          const next = new Set(prev);
                          if (e.target.checked) next.add(m);
                          else next.delete(m);
                          return next;
                        })
                      }
                      aria-label={`${MATERIAL_LABEL[m]} 첨부`}
                    />
                  </label>
                ))}
              </div>
            </div>

            <div className="kx-auc__gate">
              킨텍스 등록업체만 응찰할 수 있습니다. 미등록 업체 초대는 서버에서 차단됩니다.
            </div>

            <Button
              block
              leadingIcon={<IconPlus size={16} />}
              onClick={submitCreate}
              disabled={createM.isPending}
            >
              {createM.isPending ? '게시 중…' : '옥션 공고 게시'}
            </Button>
          </div>
        </aside>
      </div>
      {toast}
    </div>
  );
}

function WeightSlider({
  label,
  value,
  onChange,
}: {
  label: string;
  value: number;
  onChange: (v: number) => void;
}) {
  return (
    <div className="kx-weight">
      <div className="kx-weight__top">
        <span>{label}</span>
        <span className="tnum">{value}%</span>
      </div>
      <input
        type="range"
        min={0}
        max={100}
        value={value}
        onChange={(e) => onChange(Number(e.target.value))}
        aria-label={`${label} 가중치`}
      />
    </div>
  );
}

function StatusPill({ status }: { status: AuctionStatus }) {
  if (status === '진행중') return <span className="kx-auc-pill kx-auc-pill--live">진행중</span>;
  if (status === '정산중') return <span className="kx-auc-pill kx-auc-pill--settle">정산 중</span>;
  return <span className="kx-auc-pill kx-auc-pill--closed">마감 완료</span>;
}

function AuctionCard({ auction, onOpen }: { auction: AuctionSummary; onOpen: () => void }) {
  const closed = auction.status !== '진행중';
  return (
    <article
      className={`kx-auc-card kx-auc-card--${auction.accent} ${closed ? 'kx-auc-card--closed' : ''}`}
    >
      <div className="kx-auc-card__top">
        <div>
          <div className="kx-auc-card__tags">
            <span className={`kx-tag ${closed ? 'kx-tag--muted' : ''}`}>{auction.category}</span>
            <span className={`kx-tag kx-tag--type ${closed ? 'kx-tag--muted' : ''}`}>
              {auction.type}
            </span>
          </div>
          <h3 className="kx-auc-card__name">{auction.title}</h3>
        </div>
        <div className="kx-auc-card__status">
          {closed ? (
            <span className="kx-auc-pill kx-auc-pill--closed">마감 완료</span>
          ) : (
            <DdayChip dday={auction.dday} />
          )}
          <StatusPill status={auction.status} />
        </div>
      </div>

      <div className="kx-auc-card__metrics">
        <div className="kx-auc-card__metric">
          <span className="kx-auc-card__metric-label">
            {auction.awardedCompany ? '낙찰 업체' : '응찰 현황'}
          </span>
          <span className="kx-auc-card__metric-value">
            {auction.awardedCompany ?? `${auction.bidderCount}개 업체 응찰 중`}
          </span>
        </div>
        <div className="kx-auc-card__metric kx-auc-card__metric--end">
          <span className="kx-auc-card__metric-label">
            {auction.finalPrice ? '최종 낙찰가' : '현재 최저가'}
          </span>
          <span className="kx-auc-card__metric-value kx-auc-card__metric-value--price tnum">
            {auction.finalPrice != null
              ? formatWon(auction.finalPrice)
              : auction.lowestPrice != null
                ? formatWon(auction.lowestPrice)
                : '—'}
          </span>
        </div>
      </div>

      <div className="kx-auc-card__foot">
        <div className="kx-auc-card__mats">
          {auction.materials.map((m) => (
            <span key={m} className="kx-auc-card__mat">
              {MAT_ICON[m]}
              {MATERIAL_LABEL[m]}
            </span>
          ))}
        </div>
        <Button variant="secondary" onClick={onOpen}>
          상세보기
        </Button>
      </div>
    </article>
  );
}
