'use client';

/**
 * 출고 상세 페이지
 * 4개 섹션 구조: 기본정보, 수주/배송정보, 배차정보, 제품내용
 */

import { useState, useCallback, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import {
  FileText,
  ClipboardList,
  ArrowRight,
  Loader2,
  ChevronDown,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  Dialog,
  DialogContent,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  DialogDescription,
  DialogFooter,
  DialogHeader,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { DateTimePicker } from '@/components/ui/date-time-picker';
import { Label } from '@/components/ui/label';
import { PhoneInput } from '@/components/ui/phone-input';
import { DocumentViewer } from '@/components/document-system/viewer/DocumentViewer';
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@/components/ui/accordion';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { IntegratedDetailTemplate } from '@/components/templates/IntegratedDetailTemplate';
import { shipmentConfig } from './shipmentConfig';
import { getShipmentById, updateShipmentStatus } from './actions';
import {
  SHIPMENT_STATUS_LABELS,
  SHIPMENT_STATUS_STYLES,
  DELIVERY_METHOD_LABELS,
  FREIGHT_COST_LABELS,
} from './types';
import type {
  ShipmentDetail as ShipmentDetailType,
  ShipmentStatus,
  FreightCostType,
  ProductGroup,
  ProductPart,
} from './types';
import { ShippingSlip } from './documents/ShippingSlip';
import { DeliveryConfirmation } from './documents/DeliveryConfirmation';
import type { OrderDocumentDetail } from './documents/ShipmentOrderDocument';
import { getOrderDocumentDetail } from '@/components/orders/actions';
import { isNextRedirectError } from '@/lib/utils/redirect-error';
import { toast } from 'sonner';

interface ShipmentDetailProps {
  id: string;
}

// 상태 전이 맵: 현재 상태 -> 다음 가능한 상태
const STATUS_TRANSITIONS: Record<ShipmentStatus, ShipmentStatus | null> = {
  scheduled: 'ready',
  ready: 'shipping',
  shipping: 'completed',
  completed: null,
  cancelled: null,
};

export function ShipmentDetail({ id }: ShipmentDetailProps) {
  const router = useRouter();
  const [previewDocument, setPreviewDocument] = useState<'shipping' | 'delivery' | null>(null);
  const [orderDetail, setOrderDetail] = useState<OrderDocumentDetail | null>(null);
  // 상태 변경 관련 상태
  const [showStatusDialog, setShowStatusDialog] = useState(false);
  const [targetStatus, setTargetStatus] = useState<ShipmentStatus | null>(null);
  const [isChangingStatus, setIsChangingStatus] = useState(false);
  const [statusFormData, setStatusFormData] = useState({
    loadingTime: '',
    vehicleNo: '',
    driverName: '',
    driverContact: '',
    confirmedArrival: '',
  });

  // API 데이터 상태
  const [detail, setDetail] = useState<ShipmentDetailType | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [_error, setError] = useState<string | null>(null);

  // 아코디언 상태
  const [accordionValue, setAccordionValue] = useState<string[]>([]);

  // API 데이터 로드
  const loadData = useCallback(async () => {
    setIsLoading(true);
    setError(null);

    try {
      const result = await getShipmentById(id);

      if (result.success && result.data) {
        setDetail(result.data);
      } else {
        setError(result.error || '출고 정보를 찾을 수 없습니다.');
      }
    } catch (err) {
      if (isNextRedirectError(err)) throw err;
      console.error('[ShipmentDetail] loadData error:', err);
      setError('데이터를 불러오는 중 오류가 발생했습니다.');
    } finally {
      setIsLoading(false);
    }
  }, [id]);

  useEffect(() => {
    loadData();
  }, [loadData]);

  // 문서 모달 열 때 수주 BOM 데이터 로드
  useEffect(() => {
    if (!previewDocument || !detail?.orderId) {
      if (!previewDocument) setOrderDetail(null);
      return;
    }
    getOrderDocumentDetail(String(detail.orderId)).then((result) => {
      if (result.success && result.data) {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const raw = result.data as Record<string, any>;
        setOrderDetail((raw?.data ?? raw) as OrderDocumentDetail);
      }
    });
  }, [previewDocument, detail?.orderId]);

  const _handleGoBack = useCallback(() => {
    router.push('/ko/outbound/shipments');
  }, [router]);

  const handleEdit = useCallback(() => {
    router.push(`/ko/outbound/shipments/${id}?mode=edit`);
  }, [id, router]);

  const handleOpenStatusDialog = useCallback((status: ShipmentStatus) => {
    setTargetStatus(status);
    setStatusFormData({
      loadingTime: '',
      vehicleNo: '',
      driverName: '',
      driverContact: '',
      confirmedArrival: '',
    });
    setShowStatusDialog(true);
  }, []);

  const handleStatusChange = useCallback(async () => {
    if (!targetStatus) return;

    setIsChangingStatus(true);
    try {
      const additionalData: Record<string, string> = {};

      if (targetStatus === 'ready' && statusFormData.loadingTime) {
        additionalData.loadingTime = statusFormData.loadingTime;
      }
      if (targetStatus === 'shipping') {
        if (statusFormData.vehicleNo) additionalData.vehicleNo = statusFormData.vehicleNo;
        if (statusFormData.driverName) additionalData.driverName = statusFormData.driverName;
        if (statusFormData.driverContact) additionalData.driverContact = statusFormData.driverContact;
      }
      if (targetStatus === 'completed' && statusFormData.confirmedArrival) {
        additionalData.confirmedArrival = statusFormData.confirmedArrival;
      }

      const result = await updateShipmentStatus(
        id,
        targetStatus,
        Object.keys(additionalData).length > 0 ? additionalData : undefined
      );

      if (result.success && result.data) {
        setDetail(result.data);
        setShowStatusDialog(false);
      } else {
        toast.error(result.error || '상태 변경에 실패했습니다.');
      }
    } catch (err) {
      if (isNextRedirectError(err)) throw err;
      console.error('[ShipmentDetail] handleStatusChange error:', err);
      toast.error('상태 변경 중 오류가 발생했습니다.');
    } finally {
      setIsChangingStatus(false);
    }
  }, [id, targetStatus, statusFormData]);

  // 모두 펼치기/접기 처리
  const handleExpandAll = useCallback(() => {
    if (!detail) return;
    const allIds = [
      ...detail.productGroups.map(g => g.id),
      ...(detail.otherParts.length > 0 ? ['other-parts'] : []),
    ];
    setAccordionValue(allIds);
  }, [detail]);

  const handleCollapseAll = useCallback(() => {
    setAccordionValue([]);
  }, []);

  // 정보 필드 렌더링 헬퍼
  const renderInfoField = (label: string, value: React.ReactNode, className?: string) => (
    <div className={className}>
      <div className="text-sm text-muted-foreground mb-1">{label}</div>
      <div className="font-medium">{value || '-'}</div>
    </div>
  );

  const canEdit = detail ? (detail.status === 'scheduled' || detail.status === 'ready' || detail.status === 'shipping') : false;

  // 제품 부품 테이블 렌더링
  const renderPartsTable = (parts: ProductPart[]) => (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead className="w-16 text-center">순번</TableHead>
          <TableHead>품목명</TableHead>
          <TableHead className="w-32">규격</TableHead>
          <TableHead className="w-20 text-center">수량</TableHead>
          <TableHead className="w-20 text-center">단위</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {parts.map((part) => (
          <TableRow key={part.id}>
            <TableCell className="text-center">{part.seq}</TableCell>
            <TableCell>{part.itemName}</TableCell>
            <TableCell>{part.specification}</TableCell>
            <TableCell className="text-center">{part.quantity}</TableCell>
            <TableCell className="text-center">{part.unit}</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );

  // 헤더 액션 버튼 렌더링
  const renderHeaderActions = useCallback(() => {
    if (!detail) return null;

    return (
      <>
        <Button
          variant="outline"
          size="sm"
          onClick={() => setPreviewDocument('shipping')}
        >
          <FileText className="w-4 h-4 md:mr-2" />
          <span className="hidden md:inline">출고증 보기</span>
        </Button>
        <Button
          variant="outline"
          size="sm"
          onClick={() => setPreviewDocument('delivery')}
        >
          <ClipboardList className="w-4 h-4 md:mr-2" />
          <span className="hidden md:inline">납품확인서 보기</span>
        </Button>
        {STATUS_TRANSITIONS[detail.status] && detail.canShip && (
          <Button
            variant="default"
            size="sm"
            className="bg-blue-600 hover:bg-blue-700"
            onClick={() => handleOpenStatusDialog(STATUS_TRANSITIONS[detail.status]!)}
          >
            <ArrowRight className="w-4 h-4 md:mr-2" />
            <span className="hidden md:inline">{SHIPMENT_STATUS_LABELS[STATUS_TRANSITIONS[detail.status]!]}로 변경</span>
          </Button>
        )}
        {STATUS_TRANSITIONS[detail.status] && !detail.canShip && (
          <Button
            variant="outline"
            size="sm"
            disabled
            className="text-muted-foreground"
          >
            <ArrowRight className="w-4 h-4 md:mr-2" />
            <span className="hidden md:inline">출하 불가 (품질 검수 필요)</span>
          </Button>
        )}
      </>
    );
  }, [detail, handleOpenStatusDialog]);

  // 컨텐츠 렌더링
  const renderViewContent = useCallback((_data: Record<string, unknown>) => {
    if (!detail) return null;

    return (
      <div className="space-y-6">
        {/* 카드 1: 기본 정보 (읽기전용) */}
        <Card>
          <CardHeader>
            <CardTitle className="text-base">기본 정보</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-6">
              {renderInfoField('출고로트', detail.lotNo || detail.shipmentNo)}
              {renderInfoField('수주로트', detail.orderLotNo)}
              {renderInfoField('현장명', detail.siteName)}
              {renderInfoField('수주처', detail.customerName)}
              {renderInfoField('작성자', detail.registrant)}
              {renderInfoField(
                '상태',
                <Badge className={SHIPMENT_STATUS_STYLES[detail.status]}>
                  {SHIPMENT_STATUS_LABELS[detail.status]}
                </Badge>
              )}
            </div>
          </CardContent>
        </Card>

        {/* 카드 2: 수주/배송 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-base">수주/배송 정보</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-2 md:grid-cols-4 gap-6">
              {renderInfoField('출고 예정일', detail.scheduledDate)}
              {renderInfoField('출고일', detail.shipmentDate)}
              {renderInfoField(
                '배송방식',
                <Badge variant="outline">
                  {DELIVERY_METHOD_LABELS[detail.deliveryMethod]}
                </Badge>
              )}
              {renderInfoField(
                '운임비용',
                detail.freightCost
                  ? FREIGHT_COST_LABELS[detail.freightCost as FreightCostType] || detail.freightCostLabel
                  : undefined
              )}
              {renderInfoField('수신자', detail.receiver)}
              {renderInfoField('수신처', detail.receiverContact)}
            </div>
            {/* 주소 영역 */}
            <div className="mt-4 grid grid-cols-1 md:grid-cols-4 gap-6">
              <div className="md:col-span-4">
                <div className="text-sm text-muted-foreground mb-1">주소</div>
                <div className="font-medium">
                  {detail.zipCode && (
                    <span className="text-muted-foreground mr-2">[{detail.zipCode}]</span>
                  )}
                  {detail.address || detail.deliveryAddress || '-'}
                  {detail.addressDetail && (
                    <span className="ml-2">{detail.addressDetail}</span>
                  )}
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        {/* 카드 3: 배차 정보 */}
        <Card>
          <CardHeader>
            <CardTitle className="text-base">배차 정보</CardTitle>
          </CardHeader>
          <CardContent className="p-0">
            {detail.vehicleDispatches.length > 0 ? (
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>물류업체</TableHead>
                    <TableHead>입차일시</TableHead>
                    <TableHead>구분</TableHead>
                    <TableHead>차량번호</TableHead>
                    <TableHead>기사연락처</TableHead>
                    <TableHead>비고</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {detail.vehicleDispatches.map((dispatch) => (
                    <TableRow key={dispatch.id}>
                      <TableCell>{dispatch.logisticsCompany || '-'}</TableCell>
                      <TableCell>{dispatch.arrivalDateTime || '-'}</TableCell>
                      <TableCell>{dispatch.tonnage || '-'}</TableCell>
                      <TableCell>{dispatch.vehicleNo || '-'}</TableCell>
                      <TableCell>{dispatch.driverContact || '-'}</TableCell>
                      <TableCell>{dispatch.remarks || '-'}</TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            ) : (
              <div className="p-6 text-center text-muted-foreground text-sm">
                등록된 배차 정보가 없습니다.
              </div>
            )}
          </CardContent>
        </Card>

        {/* 카드 4: 제품내용 */}
        <Card>
          <CardHeader className="flex flex-row items-center justify-between">
            <CardTitle className="text-base">제품내용</CardTitle>
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button variant="outline" size="sm">
                  펼치기/접기
                  <ChevronDown className="w-4 h-4 ml-1" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end">
                <DropdownMenuItem onClick={handleExpandAll}>
                  모두 펼치기
                </DropdownMenuItem>
                <DropdownMenuItem onClick={handleCollapseAll}>
                  모두 접기
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          </CardHeader>
          <CardContent>
            {detail.productGroups.length > 0 || detail.otherParts.length > 0 ? (
              <Accordion
                type="multiple"
                value={accordionValue}
                onValueChange={setAccordionValue}
              >
                {detail.productGroups.map((group: ProductGroup) => (
                  <AccordionItem key={group.id} value={group.id}>
                    <AccordionTrigger className="hover:no-underline">
                      <div className="flex items-center gap-3">
                        <span className="font-medium">{group.productName}</span>
                        <span className="text-muted-foreground text-sm">
                          ({group.specification})
                        </span>
                        <Badge variant="secondary" className="text-xs">
                          {group.partCount}개 부품
                        </Badge>
                      </div>
                    </AccordionTrigger>
                    <AccordionContent>
                      {renderPartsTable(group.parts)}
                    </AccordionContent>
                  </AccordionItem>
                ))}
                {detail.otherParts.length > 0 && (
                  <AccordionItem value="other-parts">
                    <AccordionTrigger className="hover:no-underline">
                      <div className="flex items-center gap-3">
                        <span className="font-medium">기타부품</span>
                        <Badge variant="secondary" className="text-xs">
                          {detail.otherParts.length}개 부품
                        </Badge>
                      </div>
                    </AccordionTrigger>
                    <AccordionContent>
                      {renderPartsTable(detail.otherParts)}
                    </AccordionContent>
                  </AccordionItem>
                )}
              </Accordion>
            ) : (
              <div className="text-center text-muted-foreground text-sm py-4">
                등록된 제품이 없습니다.
              </div>
            )}
          </CardContent>
        </Card>

        {/* 비고 */}
        {detail.remarks && (
          <Card>
            <CardHeader>
              <CardTitle className="text-base">비고</CardTitle>
            </CardHeader>
            <CardContent>
              <p className="text-sm whitespace-pre-wrap">{detail.remarks}</p>
            </CardContent>
          </Card>
        )}
      </div>
    );
  }, [detail, accordionValue, handleExpandAll, handleCollapseAll]);

  return (
    <>
      <IntegratedDetailTemplate
        config={shipmentConfig}
        mode="view"
        initialData={(detail ?? undefined) as Record<string, unknown> | undefined}
        itemId={id}
        isLoading={isLoading}
        onEdit={canEdit ? handleEdit : undefined}
        renderView={renderViewContent}
        headerActions={renderHeaderActions()}
      />

      {/* 문서 미리보기 (DocumentViewer 통일 패턴) */}
      <DocumentViewer
        title={previewDocument === 'shipping' ? '출고증' : '납품확인서'}
        subtitle={detail ? `${detail.customerName} (${detail.shipmentNo})` : undefined}
        preset="readonly"
        open={previewDocument !== null}
        onOpenChange={() => setPreviewDocument(null)}
      >
        {detail && (
          <>
            {previewDocument === 'shipping' && <ShippingSlip data={detail} orderDetail={orderDetail} />}
            {previewDocument === 'delivery' && <DeliveryConfirmation data={detail} orderDetail={orderDetail} />}
          </>
        )}
      </DocumentViewer>

      {/* 상태 변경 다이얼로그 */}
      <Dialog open={showStatusDialog} onOpenChange={setShowStatusDialog}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>출고 상태 변경</DialogTitle>
            <DialogDescription>
              {detail?.status && targetStatus && (
                <span className="flex items-center gap-2 mt-2">
                  <Badge className={SHIPMENT_STATUS_STYLES[detail.status]}>
                    {SHIPMENT_STATUS_LABELS[detail.status]}
                  </Badge>
                  <ArrowRight className="w-4 h-4" />
                  <Badge className={SHIPMENT_STATUS_STYLES[targetStatus]}>
                    {SHIPMENT_STATUS_LABELS[targetStatus]}
                  </Badge>
                </span>
              )}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4 py-4">
            {targetStatus === 'ready' && (
              <div className="space-y-2">
                <Label htmlFor="loadingTime">상차 시간 (선택)</Label>
                <DateTimePicker
                  value={statusFormData.loadingTime}
                  onChange={(val) =>
                    setStatusFormData((prev) => ({ ...prev, loadingTime: val }))
                  }
                />
              </div>
            )}

            {targetStatus === 'shipping' && (
              <>
                <div className="space-y-2">
                  <Label htmlFor="vehicleNo">차량번호 (선택)</Label>
                  <Input
                    id="vehicleNo"
                    placeholder="예: 12가 3456"
                    value={statusFormData.vehicleNo}
                    onChange={(e) =>
                      setStatusFormData((prev) => ({ ...prev, vehicleNo: e.target.value }))
                    }
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="driverName">운전자명 (선택)</Label>
                  <Input
                    id="driverName"
                    placeholder="운전자 이름"
                    value={statusFormData.driverName}
                    onChange={(e) =>
                      setStatusFormData((prev) => ({ ...prev, driverName: e.target.value }))
                    }
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="driverContact">운전자 연락처 (선택)</Label>
                  <PhoneInput
                    id="driverContact"
                    placeholder="010-0000-0000"
                    value={statusFormData.driverContact}
                    onChange={(value) =>
                      setStatusFormData((prev) => ({ ...prev, driverContact: value }))
                    }
                  />
                </div>
              </>
            )}

            {targetStatus === 'completed' && (
              <div className="space-y-2">
                <Label htmlFor="confirmedArrival">도착 확인 시간 (선택)</Label>
                <DateTimePicker
                  value={statusFormData.confirmedArrival}
                  onChange={(val) =>
                    setStatusFormData((prev) => ({ ...prev, confirmedArrival: val }))
                  }
                />
              </div>
            )}
          </div>

          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setShowStatusDialog(false)}
              disabled={isChangingStatus}
            >
              취소
            </Button>
            <Button
              onClick={handleStatusChange}
              disabled={isChangingStatus}
              className="bg-blue-600 hover:bg-blue-700"
            >
              {isChangingStatus ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  변경 중...
                </>
              ) : (
                '상태 변경'
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
