"use client";

import React, { useEffect, useState, useMemo, useCallback } from "react";
import {
  Loader2, Play, Pause, CheckCircle2, AlertCircle, Timer, Package,
} from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { dataApi } from "@/lib/api/data";
import { apiClient } from "@/lib/api/client";
import { usePopEvent } from "@/hooks/pop/usePopEvent";
import { useAuth } from "@/hooks/useAuth";
import type { PopWorkDetailConfig } from "../types";
import type { TimelineProcessStep } from "../types";

// ========================================
// 타입
// ========================================

type RowData = Record<string, unknown>;

interface WorkResultRow {
  id: string;
  work_order_process_id: string;
  source_work_item_id: string;
  source_detail_id: string;
  work_phase: string;
  item_title: string;
  item_sort_order: string;
  detail_type: string;
  detail_label: string;
  detail_sort_order: string;
  spec_value: string | null;
  lower_limit: string | null;
  upper_limit: string | null;
  input_type: string | null;
  result_value: string | null;
  status: string;
  is_passed: string | null;
  recorded_by: string | null;
  recorded_at: string | null;
}

interface WorkGroup {
  phase: string;
  title: string;
  itemId: string;
  sortOrder: number;
  total: number;
  completed: number;
}

type WorkPhase = "PRE" | "IN" | "POST";
const PHASE_ORDER: Record<string, number> = { PRE: 1, IN: 2, POST: 3 };

interface ProcessTimerData {
  started_at: string | null;
  paused_at: string | null;
  total_paused_time: string | null;
  status: string;
  good_qty: string | null;
  defect_qty: string | null;
}

// ========================================
// Props
// ========================================

interface PopWorkDetailComponentProps {
  config?: PopWorkDetailConfig;
  screenId?: string;
  componentId?: string;
  currentRowSpan?: number;
  currentColSpan?: number;
}

// ========================================
// 메인 컴포넌트
// ========================================

export function PopWorkDetailComponent({
  config,
  screenId,
  componentId,
}: PopWorkDetailComponentProps) {
  const { getSharedData } = usePopEvent(screenId || "default");
  const { user } = useAuth();

  const cfg: PopWorkDetailConfig = {
    showTimer: config?.showTimer ?? true,
    showQuantityInput: config?.showQuantityInput ?? true,
    phaseLabels: config?.phaseLabels ?? { PRE: "작업 전", IN: "작업 중", POST: "작업 후" },
  };

  // parentRow에서 현재 공정 정보 추출
  const parentRow = getSharedData<RowData>("parentRow");
  const processFlow = parentRow?.__processFlow__ as TimelineProcessStep[] | undefined;
  const currentProcess = processFlow?.find((p) => p.isCurrent);
  const workOrderProcessId = currentProcess?.processId
    ? String(currentProcess.processId)
    : undefined;
  const processName = currentProcess?.processName ?? "공정 상세";

  // ========================================
  // 상태
  // ========================================

  const [allResults, setAllResults] = useState<WorkResultRow[]>([]);
  const [processData, setProcessData] = useState<ProcessTimerData | null>(null);
  const [loading, setLoading] = useState(true);
  const [selectedGroupId, setSelectedGroupId] = useState<string | null>(null);
  const [tick, setTick] = useState(Date.now());
  const [savingIds, setSavingIds] = useState<Set<string>>(new Set());

  // 수량 입력 로컬 상태
  const [goodQty, setGoodQty] = useState("");
  const [defectQty, setDefectQty] = useState("");

  // ========================================
  // D-FE1: 데이터 로드
  // ========================================

  const fetchData = useCallback(async () => {
    if (!workOrderProcessId) {
      setLoading(false);
      return;
    }

    try {
      setLoading(true);

      const [resultRes, processRes] = await Promise.all([
        dataApi.getTableData("process_work_result", {
          size: 500,
          filters: { work_order_process_id: workOrderProcessId },
        }),
        dataApi.getTableData("work_order_process", {
          size: 1,
          filters: { id: workOrderProcessId },
        }),
      ]);

      setAllResults((resultRes.data ?? []) as unknown as WorkResultRow[]);

      const proc = (processRes.data?.[0] ?? null) as ProcessTimerData | null;
      setProcessData(proc);
      if (proc) {
        setGoodQty(proc.good_qty ?? "");
        setDefectQty(proc.defect_qty ?? "");
      }
    } catch {
      toast.error("데이터를 불러오는데 실패했습니다.");
    } finally {
      setLoading(false);
    }
  }, [workOrderProcessId]);

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

  // ========================================
  // D-FE2: 좌측 사이드바 - 작업항목 그룹핑
  // ========================================

  const groups = useMemo<WorkGroup[]>(() => {
    const map = new Map<string, WorkGroup>();
    for (const row of allResults) {
      const key = row.source_work_item_id;
      if (!map.has(key)) {
        map.set(key, {
          phase: row.work_phase,
          title: row.item_title,
          itemId: key,
          sortOrder: parseInt(row.item_sort_order || "0", 10),
          total: 0,
          completed: 0,
        });
      }
      const g = map.get(key)!;
      g.total++;
      if (row.status === "completed") g.completed++;
    }
    return Array.from(map.values()).sort(
      (a, b) =>
        (PHASE_ORDER[a.phase] ?? 9) - (PHASE_ORDER[b.phase] ?? 9) ||
        a.sortOrder - b.sortOrder
    );
  }, [allResults]);

  // phase별로 그룹핑
  const groupsByPhase = useMemo(() => {
    const result: Record<string, WorkGroup[]> = {};
    for (const g of groups) {
      if (!result[g.phase]) result[g.phase] = [];
      result[g.phase].push(g);
    }
    return result;
  }, [groups]);

  // 첫 그룹 자동 선택
  useEffect(() => {
    if (groups.length > 0 && !selectedGroupId) {
      setSelectedGroupId(groups[0].itemId);
    }
  }, [groups, selectedGroupId]);

  // ========================================
  // D-FE3: 우측 체크리스트
  // ========================================

  const currentItems = useMemo(
    () =>
      allResults
        .filter((r) => r.source_work_item_id === selectedGroupId)
        .sort((a, b) => parseInt(a.detail_sort_order || "0", 10) - parseInt(b.detail_sort_order || "0", 10)),
    [allResults, selectedGroupId]
  );

  const saveResultValue = useCallback(
    async (
      rowId: string,
      resultValue: string,
      isPassed: string | null,
      newStatus: string
    ) => {
      setSavingIds((prev) => new Set(prev).add(rowId));
      try {
        await apiClient.post("/pop/execute-action", {
          tasks: [
            { type: "data-update", targetTable: "process_work_result", targetColumn: "result_value", value: resultValue, items: [{ id: rowId }] },
            { type: "data-update", targetTable: "process_work_result", targetColumn: "status", value: newStatus, items: [{ id: rowId }] },
            ...(isPassed !== null
              ? [{ type: "data-update", targetTable: "process_work_result", targetColumn: "is_passed", value: isPassed, items: [{ id: rowId }] }]
              : []),
            { type: "data-update", targetTable: "process_work_result", targetColumn: "recorded_by", value: user?.user_id ?? "", items: [{ id: rowId }] },
            { type: "data-update", targetTable: "process_work_result", targetColumn: "recorded_at", value: new Date().toISOString(), items: [{ id: rowId }] },
          ],
          data: { items: [{ id: rowId }], fieldValues: {} },
        });

        setAllResults((prev) =>
          prev.map((r) =>
            r.id === rowId
              ? {
                  ...r,
                  result_value: resultValue,
                  status: newStatus,
                  is_passed: isPassed,
                  recorded_by: user?.user_id ?? null,
                  recorded_at: new Date().toISOString(),
                }
              : r
          )
        );
      } catch {
        toast.error("저장에 실패했습니다.");
      } finally {
        setSavingIds((prev) => {
          const next = new Set(prev);
          next.delete(rowId);
          return next;
        });
      }
    },
    [user?.user_id]
  );

  // ========================================
  // D-FE4: 타이머
  // ========================================

  useEffect(() => {
    if (!cfg.showTimer || !processData?.started_at) return;
    const id = setInterval(() => setTick(Date.now()), 1000);
    return () => clearInterval(id);
  }, [cfg.showTimer, processData?.started_at]);

  const elapsedMs = useMemo(() => {
    if (!processData?.started_at) return 0;
    const now = tick;
    const totalMs = now - new Date(processData.started_at).getTime();
    const pausedSec = parseInt(processData.total_paused_time || "0", 10);
    const currentPauseMs = processData.paused_at
      ? now - new Date(processData.paused_at).getTime()
      : 0;
    return Math.max(0, totalMs - pausedSec * 1000 - currentPauseMs);
  }, [processData?.started_at, processData?.paused_at, processData?.total_paused_time, tick]);

  const formattedTime = useMemo(() => {
    const totalSec = Math.floor(elapsedMs / 1000);
    const h = String(Math.floor(totalSec / 3600)).padStart(2, "0");
    const m = String(Math.floor((totalSec % 3600) / 60)).padStart(2, "0");
    const s = String(totalSec % 60).padStart(2, "0");
    return `${h}:${m}:${s}`;
  }, [elapsedMs]);

  const isPaused = !!processData?.paused_at;
  const isStarted = !!processData?.started_at;

  const handleTimerAction = useCallback(
    async (action: "start" | "pause" | "resume") => {
      if (!workOrderProcessId) return;
      try {
        await apiClient.post("/api/pop/production/timer", {
          workOrderProcessId,
          action,
        });
        // 타이머 상태 새로고침
        const res = await dataApi.getTableData("work_order_process", {
          size: 1,
          filters: { id: workOrderProcessId },
        });
        const proc = (res.data?.[0] ?? null) as ProcessTimerData | null;
        if (proc) setProcessData(proc);
      } catch {
        toast.error("타이머 제어에 실패했습니다.");
      }
    },
    [workOrderProcessId]
  );

  // ========================================
  // D-FE5: 수량 등록 + 완료
  // ========================================

  const handleQuantityRegister = useCallback(async () => {
    if (!workOrderProcessId) return;
    try {
      await apiClient.post("/pop/execute-action", {
        tasks: [
          { type: "data-update", targetTable: "work_order_process", targetColumn: "good_qty", value: goodQty || "0", items: [{ id: workOrderProcessId }] },
          { type: "data-update", targetTable: "work_order_process", targetColumn: "defect_qty", value: defectQty || "0", items: [{ id: workOrderProcessId }] },
        ],
        data: { items: [{ id: workOrderProcessId }], fieldValues: {} },
      });
      toast.success("수량이 등록되었습니다.");
    } catch {
      toast.error("수량 등록에 실패했습니다.");
    }
  }, [workOrderProcessId, goodQty, defectQty]);

  const handleProcessComplete = useCallback(async () => {
    if (!workOrderProcessId) return;
    try {
      await apiClient.post("/pop/execute-action", {
        tasks: [
          { type: "data-update", targetTable: "work_order_process", targetColumn: "status", value: "completed", items: [{ id: workOrderProcessId }] },
          { type: "data-update", targetTable: "work_order_process", targetColumn: "completed_at", value: new Date().toISOString(), items: [{ id: workOrderProcessId }] },
        ],
        data: { items: [{ id: workOrderProcessId }], fieldValues: {} },
      });
      toast.success("공정이 완료되었습니다.");
      setProcessData((prev) =>
        prev ? { ...prev, status: "completed" } : prev
      );
    } catch {
      toast.error("공정 완료 처리에 실패했습니다.");
    }
  }, [workOrderProcessId]);

  // ========================================
  // 안전 장치
  // ========================================

  if (!parentRow) {
    return (
      <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
        <AlertCircle className="mr-2 h-4 w-4" />
        카드를 선택해주세요
      </div>
    );
  }

  if (!workOrderProcessId) {
    return (
      <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
        <AlertCircle className="mr-2 h-4 w-4" />
        공정 정보를 찾을 수 없습니다
      </div>
    );
  }

  if (loading) {
    return (
      <div className="flex h-full items-center justify-center">
        <Loader2 className="h-6 w-6 animate-spin text-primary" />
      </div>
    );
  }

  if (allResults.length === 0) {
    return (
      <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
        <AlertCircle className="mr-2 h-4 w-4" />
        작업기준이 등록되지 않았습니다
      </div>
    );
  }

  const isProcessCompleted = processData?.status === "completed";

  // ========================================
  // 렌더링
  // ========================================

  return (
    <div className="flex h-full flex-col">
      {/* 헤더 */}
      <div className="flex items-center justify-between border-b px-3 py-2">
        <h3 className="text-sm font-semibold">{processName}</h3>
        {cfg.showTimer && (
          <div className="flex items-center gap-2">
            <Timer className="h-4 w-4 text-muted-foreground" />
            <span className="font-mono text-sm font-medium tabular-nums">
              {formattedTime}
            </span>
            {!isProcessCompleted && (
              <>
                {!isStarted && (
                  <Button size="sm" variant="outline" className="h-7 px-2 text-xs" onClick={() => handleTimerAction("start")}>
                    <Play className="mr-1 h-3 w-3" />
                    시작
                  </Button>
                )}
                {isStarted && !isPaused && (
                  <Button size="sm" variant="outline" className="h-7 px-2 text-xs" onClick={() => handleTimerAction("pause")}>
                    <Pause className="mr-1 h-3 w-3" />
                    정지
                  </Button>
                )}
                {isStarted && isPaused && (
                  <Button size="sm" variant="outline" className="h-7 px-2 text-xs" onClick={() => handleTimerAction("resume")}>
                    <Play className="mr-1 h-3 w-3" />
                    재개
                  </Button>
                )}
              </>
            )}
          </div>
        )}
      </div>

      {/* 본문: 좌측 사이드바 + 우측 체크리스트 */}
      <div className="flex flex-1 overflow-hidden">
        {/* 좌측 사이드바 */}
        <div className="w-40 shrink-0 overflow-y-auto border-r bg-muted/30">
          {(["PRE", "IN", "POST"] as WorkPhase[]).map((phase) => {
            const phaseGroups = groupsByPhase[phase];
            if (!phaseGroups || phaseGroups.length === 0) return null;
            return (
              <div key={phase}>
                <div className="px-3 pb-1 pt-2 text-[10px] font-semibold uppercase text-muted-foreground">
                  {cfg.phaseLabels[phase] ?? phase}
                </div>
                {phaseGroups.map((g) => (
                  <button
                    key={g.itemId}
                    className={cn(
                      "flex w-full flex-col px-3 py-1.5 text-left transition-colors",
                      selectedGroupId === g.itemId
                        ? "bg-primary/10 text-primary"
                        : "hover:bg-muted/60"
                    )}
                    onClick={() => setSelectedGroupId(g.itemId)}
                  >
                    <span className="text-xs font-medium leading-tight">
                      {g.title}
                    </span>
                    <span className="text-[10px] text-muted-foreground">
                      {g.completed}/{g.total} 완료
                    </span>
                  </button>
                ))}
              </div>
            );
          })}
        </div>

        {/* 우측 체크리스트 */}
        <div className="flex-1 overflow-y-auto p-3">
          {selectedGroupId && (
            <div className="space-y-2">
              {currentItems.map((item) => (
                <ChecklistItem
                  key={item.id}
                  item={item}
                  saving={savingIds.has(item.id)}
                  disabled={isProcessCompleted}
                  onSave={saveResultValue}
                />
              ))}
            </div>
          )}
        </div>
      </div>

      {/* 하단: 수량 입력 + 완료 */}
      {cfg.showQuantityInput && (
        <div className="flex items-center gap-2 border-t px-3 py-2">
          <Package className="h-4 w-4 shrink-0 text-muted-foreground" />
          <div className="flex items-center gap-1">
            <span className="text-xs text-muted-foreground">양품</span>
            <Input
              type="number"
              className="h-7 w-20 text-xs"
              value={goodQty}
              onChange={(e) => setGoodQty(e.target.value)}
              disabled={isProcessCompleted}
            />
          </div>
          <div className="flex items-center gap-1">
            <span className="text-xs text-muted-foreground">불량</span>
            <Input
              type="number"
              className="h-7 w-20 text-xs"
              value={defectQty}
              onChange={(e) => setDefectQty(e.target.value)}
              disabled={isProcessCompleted}
            />
          </div>
          <Button
            size="sm"
            variant="outline"
            className="h-7 text-xs"
            onClick={handleQuantityRegister}
            disabled={isProcessCompleted}
          >
            수량 등록
          </Button>
          <div className="flex-1" />
          {!isProcessCompleted && (
            <Button
              size="sm"
              variant="default"
              className="h-7 text-xs"
              onClick={handleProcessComplete}
            >
              <CheckCircle2 className="mr-1 h-3 w-3" />
              공정 완료
            </Button>
          )}
          {isProcessCompleted && (
            <Badge variant="outline" className="text-xs text-green-600">
              완료됨
            </Badge>
          )}
        </div>
      )}
    </div>
  );
}

// ========================================
// 체크리스트 개별 항목
// ========================================

interface ChecklistItemProps {
  item: WorkResultRow;
  saving: boolean;
  disabled: boolean;
  onSave: (
    rowId: string,
    resultValue: string,
    isPassed: string | null,
    newStatus: string
  ) => void;
}

function ChecklistItem({ item, saving, disabled, onSave }: ChecklistItemProps) {
  const isSaving = saving;
  const isDisabled = disabled || isSaving;

  switch (item.detail_type) {
    case "check":
      return <CheckItem item={item} disabled={isDisabled} saving={isSaving} onSave={onSave} />;
    case "inspect":
      return <InspectItem item={item} disabled={isDisabled} saving={isSaving} onSave={onSave} />;
    case "input":
      return <InputItem item={item} disabled={isDisabled} saving={isSaving} onSave={onSave} />;
    case "procedure":
      return <ProcedureItem item={item} disabled={isDisabled} saving={isSaving} onSave={onSave} />;
    case "material":
      return <MaterialItem item={item} disabled={isDisabled} saving={isSaving} onSave={onSave} />;
    default:
      return (
        <div className="rounded border p-2 text-xs text-muted-foreground">
          알 수 없는 유형: {item.detail_type}
        </div>
      );
  }
}

// ===== check: 체크박스 =====

function CheckItem({
  item,
  disabled,
  saving,
  onSave,
}: {
  item: WorkResultRow;
  disabled: boolean;
  saving: boolean;
  onSave: ChecklistItemProps["onSave"];
}) {
  const checked = item.result_value === "Y";
  return (
    <div
      className={cn(
        "flex items-center gap-2 rounded border px-3 py-2",
        item.status === "completed" && "bg-green-50 border-green-200"
      )}
    >
      <Checkbox
        checked={checked}
        disabled={disabled}
        onCheckedChange={(v) => {
          const val = v ? "Y" : "N";
          onSave(item.id, val, v ? "Y" : "N", v ? "completed" : "pending");
        }}
      />
      <span className="flex-1 text-xs">{item.detail_label}</span>
      {saving && <Loader2 className="h-3 w-3 animate-spin" />}
      {item.status === "completed" && !saving && (
        <Badge variant="outline" className="text-[10px] text-green-600">
          완료
        </Badge>
      )}
    </div>
  );
}

// ===== inspect: 측정값 입력 (범위 판정) =====

function InspectItem({
  item,
  disabled,
  saving,
  onSave,
}: {
  item: WorkResultRow;
  disabled: boolean;
  saving: boolean;
  onSave: ChecklistItemProps["onSave"];
}) {
  const [inputVal, setInputVal] = useState(item.result_value ?? "");
  const lower = parseFloat(item.lower_limit ?? "");
  const upper = parseFloat(item.upper_limit ?? "");
  const hasRange = !isNaN(lower) && !isNaN(upper);

  const handleBlur = () => {
    if (!inputVal || disabled) return;
    const numVal = parseFloat(inputVal);
    let passed: string | null = null;
    if (hasRange) {
      passed = numVal >= lower && numVal <= upper ? "Y" : "N";
    }
    onSave(item.id, inputVal, passed, "completed");
  };

  const isPassed = item.is_passed;

  return (
    <div
      className={cn(
        "rounded border px-3 py-2",
        isPassed === "Y" && "bg-green-50 border-green-200",
        isPassed === "N" && "bg-red-50 border-red-200"
      )}
    >
      <div className="mb-1 flex items-center justify-between">
        <span className="text-xs font-medium">{item.detail_label}</span>
        {hasRange && (
          <span className="text-[10px] text-muted-foreground">
            기준: {item.lower_limit} ~ {item.upper_limit}
            {item.spec_value ? ` (표준: ${item.spec_value})` : ""}
          </span>
        )}
      </div>
      <div className="flex items-center gap-2">
        <Input
          type="number"
          className="h-7 w-28 text-xs"
          value={inputVal}
          onChange={(e) => setInputVal(e.target.value)}
          onBlur={handleBlur}
          disabled={disabled}
          placeholder="측정값 입력"
        />
        {saving && <Loader2 className="h-3 w-3 animate-spin" />}
        {isPassed === "Y" && !saving && (
          <Badge variant="outline" className="text-[10px] text-green-600">합격</Badge>
        )}
        {isPassed === "N" && !saving && (
          <Badge variant="outline" className="text-[10px] text-red-600">불합격</Badge>
        )}
      </div>
    </div>
  );
}

// ===== input: 자유 입력 =====

function InputItem({
  item,
  disabled,
  saving,
  onSave,
}: {
  item: WorkResultRow;
  disabled: boolean;
  saving: boolean;
  onSave: ChecklistItemProps["onSave"];
}) {
  const [inputVal, setInputVal] = useState(item.result_value ?? "");
  const inputType = item.input_type === "number" ? "number" : "text";

  const handleBlur = () => {
    if (!inputVal || disabled) return;
    onSave(item.id, inputVal, null, "completed");
  };

  return (
    <div
      className={cn(
        "rounded border px-3 py-2",
        item.status === "completed" && "bg-green-50 border-green-200"
      )}
    >
      <div className="mb-1 text-xs font-medium">{item.detail_label}</div>
      <div className="flex items-center gap-2">
        <Input
          type={inputType}
          className="h-7 flex-1 text-xs"
          value={inputVal}
          onChange={(e) => setInputVal(e.target.value)}
          onBlur={handleBlur}
          disabled={disabled}
          placeholder="값 입력"
        />
        {saving && <Loader2 className="h-3 w-3 animate-spin" />}
      </div>
    </div>
  );
}

// ===== procedure: 절차 확인 (읽기 전용 + 체크) =====

function ProcedureItem({
  item,
  disabled,
  saving,
  onSave,
}: {
  item: WorkResultRow;
  disabled: boolean;
  saving: boolean;
  onSave: ChecklistItemProps["onSave"];
}) {
  const checked = item.result_value === "Y";
  return (
    <div
      className={cn(
        "rounded border px-3 py-2",
        item.status === "completed" && "bg-green-50 border-green-200"
      )}
    >
      <div className="mb-1 text-xs text-muted-foreground">
        {item.spec_value || item.detail_label}
      </div>
      <div className="flex items-center gap-2">
        <Checkbox
          checked={checked}
          disabled={disabled}
          onCheckedChange={(v) => {
            onSave(item.id, v ? "Y" : "N", null, v ? "completed" : "pending");
          }}
        />
        <span className="text-xs">확인</span>
        {saving && <Loader2 className="h-3 w-3 animate-spin" />}
      </div>
    </div>
  );
}

// ===== material: 자재/LOT 입력 =====

function MaterialItem({
  item,
  disabled,
  saving,
  onSave,
}: {
  item: WorkResultRow;
  disabled: boolean;
  saving: boolean;
  onSave: ChecklistItemProps["onSave"];
}) {
  const [inputVal, setInputVal] = useState(item.result_value ?? "");

  const handleBlur = () => {
    if (!inputVal || disabled) return;
    onSave(item.id, inputVal, null, "completed");
  };

  return (
    <div
      className={cn(
        "rounded border px-3 py-2",
        item.status === "completed" && "bg-green-50 border-green-200"
      )}
    >
      <div className="mb-1 text-xs font-medium">{item.detail_label}</div>
      <div className="flex items-center gap-2">
        <Input
          className="h-7 flex-1 text-xs"
          value={inputVal}
          onChange={(e) => setInputVal(e.target.value)}
          onBlur={handleBlur}
          disabled={disabled}
          placeholder="LOT 번호 입력"
        />
        {saving && <Loader2 className="h-3 w-3 animate-spin" />}
      </div>
    </div>
  );
}
