'use client';

/**
 * 일상점검표 - 그리드 매트릭스 뷰
 *
 * 설비별 점검항목 × 날짜 매트릭스
 * 셀 클릭으로 ○/X/△ 토글
 */

import { useState, useEffect, useCallback, useRef } from 'react';
import { useSearchParams } from 'next/navigation';
import { Loader2 } from 'lucide-react';
import { toast } from 'sonner';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Label } from '@/components/ui/label';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import {
  getInspectionGrid,
  toggleInspectionResult,
  resetInspections,
  getEquipmentOptions,
} from '@/components/quality/EquipmentManagement/actions';
import type {
  EquipmentOptions,
  InspectionCycle,
  InspectionResult,
} from '@/components/quality/EquipmentManagement/types';
import {
  INSPECTION_CYCLE_LABEL,
  INSPECTION_CYCLES,
  INSPECTION_RESULT_SYMBOL,
} from '@/components/quality/EquipmentManagement/types';

interface GridEquipment {
  id: number;
  equipmentCode: string;
  name: string;
}

interface GridTemplate {
  id: number;
  itemNo: string;
  checkPoint: string;
  checkItem: string;
}

interface GridRow {
  equipment: GridEquipment;
  templates: GridTemplate[];
  details: Record<string, InspectionResult>;
  canInspect: boolean;
  overallJudgment: string | null;
}

interface GridData {
  rows: GridRow[];
  labels: string[];
  nonWorkingDays: string[];
}

const YEAR_OPTIONS = Array.from({ length: 10 }, (_, i) => 2021 + i);
const MONTH_OPTIONS = Array.from({ length: 12 }, (_, i) => i + 1);

export function EquipmentInspectionGrid() {
  const searchParams = useSearchParams();
  const [cycle, setCycle] = useState<InspectionCycle>('daily');
  const [year, setYear] = useState(() => new Date().getFullYear());
  const [month, setMonth] = useState(() => new Date().getMonth() + 1);
  const period = `${year}-${String(month).padStart(2, '0')}`;
  const [lineFilter, setLineFilter] = useState<string>('all');
  const [equipmentFilter, setEquipmentFilter] = useState<string>(() => {
    if (typeof window === 'undefined') return 'all';
    const eqId = new URLSearchParams(window.location.search).get('equipment_id');
    return eqId || 'all';
  });
  const [options, setOptions] = useState<EquipmentOptions | null>(null);
  const [gridData, setGridData] = useState<GridData>({ rows: [], labels: [], nonWorkingDays: [] });
  const [isLoading, setIsLoading] = useState(true);
  const [showReset, setShowReset] = useState(false);

  // 드래그 스크롤
  const scrollRef = useRef<HTMLDivElement>(null);
  const isDragging = useRef(false);
  const startX = useRef(0);
  const scrollLeft = useRef(0);

  const handleMouseDown = useCallback((e: React.MouseEvent) => {
    const el = scrollRef.current;
    if (!el) return;
    isDragging.current = true;
    startX.current = e.pageX - el.offsetLeft;
    scrollLeft.current = el.scrollLeft;
    el.style.cursor = 'grabbing';
    el.style.userSelect = 'none';
  }, []);

  const handleMouseMove = useCallback((e: React.MouseEvent) => {
    if (!isDragging.current) return;
    const el = scrollRef.current;
    if (!el) return;
    e.preventDefault();
    const x = e.pageX - el.offsetLeft;
    el.scrollLeft = scrollLeft.current - (x - startX.current);
  }, []);

  const handleMouseUp = useCallback(() => {
    isDragging.current = false;
    const el = scrollRef.current;
    if (el) {
      el.style.cursor = 'grab';
      el.style.userSelect = '';
    }
  }, []);

  // 옵션 로드
  useEffect(() => {
    getEquipmentOptions().then((r) => {
      if (r.success && r.data) setOptions(r.data);
    });
  }, []);

  // 그리드 데이터 로드
  const loadGrid = useCallback(async () => {
    setIsLoading(true);
    const result = await getInspectionGrid({
      cycle,
      period,
      productionLine: lineFilter,
      equipmentId: equipmentFilter !== 'all' ? Number(equipmentFilter) : undefined,
    });
    if (result.success && result.data) {
      // API는 배열을 반환: [{ equipment, templates, inspection, details, labels, can_inspect }, ...]
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const apiItems = Array.isArray(result.data) ? result.data as any[] : [];
      const rows: GridRow[] = apiItems.map((item) => {
        // details: API는 "templateItemId_date" 키의 배열 or 빈 배열 → Record<string, InspectionResult> 변환
        const detailMap: Record<string, InspectionResult> = {};
        if (item.details && typeof item.details === 'object' && !Array.isArray(item.details)) {
          for (const [key, arr] of Object.entries(item.details)) {
            if (Array.isArray(arr) && arr.length > 0) {
              detailMap[key] = (arr[0] as { result: InspectionResult }).result;
            }
          }
        }
        return {
          equipment: {
            id: item.equipment?.id,
            equipmentCode: item.equipment?.equipment_code || '',
            name: item.equipment?.name || '',
          },
          templates: (item.templates || []).map((t: Record<string, unknown>) => ({
            id: t.id,
            itemNo: String(t.item_no ?? ''),
            checkPoint: t.check_point || '',
            checkItem: t.check_item || '',
          })),
          details: detailMap,
          canInspect: item.can_inspect ?? false,
          overallJudgment: item.inspection?.overall_judgment ?? null,
        };
      });
      // labels: 첫 번째 아이템의 labels (object {"1":"1",...} → string[] 변환)
      const rawLabels = apiItems.length > 0 ? apiItems[0].labels : {};
      const labels: string[] = typeof rawLabels === 'object' && !Array.isArray(rawLabels)
        ? Object.keys(rawLabels).sort((a, b) => Number(a) - Number(b))
        : Array.isArray(rawLabels) ? rawLabels : [];
      // 주말(토/일) 계산
      const [y, m] = period.split('-').map(Number);
      const weekends = new Set<string>();
      const daysInMonth = new Date(y, m, 0).getDate();
      for (let d = 1; d <= daysInMonth; d++) {
        const dow = new Date(y, m - 1, d).getDay();
        if (dow === 0 || dow === 6) weekends.add(String(d));
      }
      // API에서 받은 임시휴일 추가 (형식: "2026-03-17" → 일자 "17"으로 변환)
      const apiHolidays: string[] = apiItems.length > 0 ? (apiItems[0].non_working_days ?? []) : [];
      for (const dateStr of apiHolidays) {
        const day = String(Number(dateStr.split('-')[2]));
        weekends.add(day);
      }
      setGridData({ rows, labels, nonWorkingDays: Array.from(weekends) });
    } else {
      setGridData({ rows: [], labels: [], nonWorkingDays: [] });
    }
    setIsLoading(false);
  }, [cycle, period, lineFilter, equipmentFilter]);

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

  // 셀 클릭 토글
  const handleCellClick = useCallback(async (
    equipmentId: number,
    templateItemId: number,
    dayLabel: string
  ) => {
    // label("1","2"...) → full date("2026-03-01")
    const fullDate = `${period}-${dayLabel.padStart(2, '0')}`;
    const result = await toggleInspectionResult({
      equipmentId,
      templateItemId,
      checkDate: fullDate,
      cycle,
    });
    if (result.success && result.data) {
      setGridData((prev) => {
        if (!prev) return prev;
        const newRows = prev.rows.map((row) => {
          if (row.equipment.id !== equipmentId) return row;
          const key = `${templateItemId}_${dayLabel}`;
          return {
            ...row,
            details: {
              ...row.details,
              [key]: result.data!.result,
            },
          };
        });
        return { ...prev, rows: newRows };
      });
    } else {
      const errorMsg = result.error?.includes('non_working_day')
        ? '비근무일에는 점검을 입력할 수 없습니다.'
        : result.error?.includes('no_inspect_permission')
          ? '담당자만 점검을 입력할 수 있습니다.'
          : result.error || '점검 결과 변경에 실패했습니다.';
      toast.error(errorMsg);
    }
  }, [cycle, period]);

  // 전체 초기화
  const handleReset = useCallback(async () => {
    const result = await resetInspections({ cycle, period });
    if (result.success) {
      toast.success(`${result.data?.deleted_count || 0}건의 점검 데이터가 초기화되었습니다.`);
      setShowReset(false);
      await loadGrid();
    } else {
      toast.error(result.error || '초기화에 실패했습니다.');
    }
  }, [cycle, period, loadGrid]);

  const getResultSymbol = (result: InspectionResult): string => {
    if (!result) return '';
    return INSPECTION_RESULT_SYMBOL[result] || '';
  };

  const getResultColor = (result: InspectionResult): string => {
    if (!result) return '';
    if (result === 'good') return 'text-green-600';
    if (result === 'bad') return 'text-red-600';
    if (result === 'repaired') return 'text-yellow-600';
    return '';
  };

  return (
    <div className="space-y-6 p-3 md:p-6">
      <h1 className="text-xl font-bold">일상점검표</h1>

      {/* 주기 탭 버튼 */}
      <div className="grid grid-cols-3 gap-1 border-b pb-1 md:flex md:items-center md:gap-1 md:pb-0">
        {INSPECTION_CYCLES.map((c) => (
          <button
            key={c}
            className={`px-3 py-2 text-sm font-medium border-b-2 transition-colors text-center ${
              cycle === c
                ? 'border-blue-600 text-blue-600'
                : 'border-transparent text-muted-foreground hover:text-foreground'
            }`}
            onClick={() => setCycle(c)}
          >
            {INSPECTION_CYCLE_LABEL[c]}
          </button>
        ))}
      </div>

      {/* 필터: 점검년월 / 생산라인 / 설비 / 조회 / 전체 초기화 */}
      <Card>
        <CardContent className="py-5 px-6">
          <div className="flex flex-wrap items-end gap-6">
            <div className="space-y-1.5">
              <Label className="text-xs text-muted-foreground">점검년월</Label>
              <div className="flex items-center gap-2">
                <Select value={String(year)} onValueChange={(v) => setYear(Number(v))}>
                  <SelectTrigger className="w-[100px] h-10">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {YEAR_OPTIONS.map(y => (
                      <SelectItem key={y} value={String(y)}>{y}년</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <Select value={String(month)} onValueChange={(v) => setMonth(Number(v))}>
                  <SelectTrigger className="w-[80px] h-10">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {MONTH_OPTIONS.map(m => (
                      <SelectItem key={m} value={String(m)}>{m}월</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            </div>
            <div className="space-y-1.5">
              <Label className="text-xs text-muted-foreground">생산라인</Label>
              <Select value={lineFilter} onValueChange={setLineFilter}>
                <SelectTrigger className="w-[180px] h-10">
                  <SelectValue placeholder="전체" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">전체</SelectItem>
                  {(options?.productionLines || []).map((line) => (
                    <SelectItem key={line} value={line}>
                      {line}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label className="text-xs text-muted-foreground">설비</Label>
              <Select value={equipmentFilter} onValueChange={setEquipmentFilter}>
                <SelectTrigger className="w-[180px] h-10">
                  <SelectValue placeholder="전체" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">전체</SelectItem>
                  {(options?.equipmentList || []).map((eq) => (
                    <SelectItem key={eq.id} value={String(eq.id)}>
                      {eq.equipmentCode} {eq.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <Button
              variant="outline"
              className="h-10 text-red-600 border-red-300 hover:bg-red-50"
              onClick={() => setShowReset(true)}
            >
              전체 초기화
            </Button>
          </div>
        </CardContent>
      </Card>

      {/* 그리드 */}
      {isLoading ? (
        <div className="flex justify-center py-12">
          <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
        </div>
      ) : gridData.rows.length === 0 ? (
        <Card>
          <CardContent className="p-0">
            <div className="flex items-center justify-center" style={{ minHeight: 240 }}>
              <div className="text-center space-y-3">
                <p className="text-red-500 font-bold text-base">점검 가능한 설비가 없습니다.</p>
                <p className="text-sm text-muted-foreground">
                  설비 등록대장에서 해당 주기의 점검항목을 추가해주세요.
                </p>
              </div>
            </div>
          </CardContent>
        </Card>
      ) : (
        <Card>
          <CardHeader>
            <CardTitle className="text-base">
              {INSPECTION_CYCLE_LABEL[cycle]} 점검표 - {period}
            </CardTitle>
          </CardHeader>
          <CardContent className="px-2 md:px-6">
            {(() => {
              const isMobile = typeof window !== 'undefined' && window.innerWidth < 640;
              const COL1 = isMobile ? 70 : 120; // 설비
              const COL2 = isMobile ? 56 : 100; // 점검부위
              const COL3 = isMobile ? 56 : 100; // 점검항목
              const bc = '#e5e7eb'; // border color
              const stickyHead = (left: number, w: number) => ({
                position: 'sticky' as const, left, width: w, minWidth: w, zIndex: 20,
                background: '#f3f4f6',
                borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`,
              });
              const stickyBody = (left: number, w: number) => ({
                position: 'sticky' as const, left, width: w, minWidth: w, zIndex: 10,
                background: '#fff',
                borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`,
              });
              const normalHead = (w: number) => ({
                width: w, minWidth: w,
                background: '#f3f4f6',
                borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`,
              });
              const normalBody = (w: number) => ({
                width: w, minWidth: w,
                borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`,
              });
              const lastStickyHead = (left: number, w: number) => ({
                ...stickyHead(left, w),
                boxShadow: '4px 0 6px -2px rgba(0,0,0,0.08)',
              });
              const lastStickyBody = (left: number, w: number) => ({
                ...stickyBody(left, w),
                boxShadow: '4px 0 6px -2px rgba(0,0,0,0.08)',
              });
              return (
            <div
              ref={scrollRef}
              className="overflow-x-auto cursor-grab"
              onMouseDown={handleMouseDown}
              onMouseMove={handleMouseMove}
              onMouseUp={handleMouseUp}
              onMouseLeave={handleMouseUp}
            >
            <table className="w-full text-xs" style={{ borderCollapse: 'separate', borderSpacing: 0 }}>
              <thead>
                <tr>
                  <th className="p-1.5 text-left" style={{ ...(isMobile ? lastStickyHead(0, COL1) : stickyHead(0, COL1)), borderLeft: `1px solid ${bc}`, borderTop: `1px solid ${bc}` }}>설비</th>
                  <th className="p-1.5 text-left" style={{ ...(isMobile ? { ...normalHead(COL2), borderTop: `1px solid ${bc}` } : { ...stickyHead(COL1, COL2), borderTop: `1px solid ${bc}` }) }}>점검부위</th>
                  <th className="p-1.5 text-left" style={{ ...(isMobile ? { ...normalHead(COL3), borderTop: `1px solid ${bc}` } : { ...lastStickyHead(COL1 + COL2, COL3), borderTop: `1px solid ${bc}` }) }}>점검항목</th>
                  {gridData.labels.map((label) => {
                    const isHoliday = gridData.nonWorkingDays.includes(label);
                    return (
                    <th
                      key={label}
                      className="p-1.5 text-center min-w-[36px]"
                      style={{
                        background: isHoliday ? '#fef2f2' : '#f3f4f6',
                        color: isHoliday ? '#dc2626' : undefined,
                        fontWeight: isHoliday ? 700 : undefined,
                        borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`, borderTop: `1px solid ${bc}`,
                      }}
                    >
                      {label.split('-').pop()}
                    </th>
                    );
                  })}
                  <th className="p-1.5 text-center min-w-[40px]" style={{ background: '#f3f4f6', borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`, borderTop: `1px solid ${bc}` }}>판정</th>
                </tr>
              </thead>
              <tbody>
                {gridData.rows.map((row) =>
                  row.templates.length === 0 ? (
                    <tr key={row.equipment.id}>
                      <td className="p-1.5" style={{ ...(isMobile ? lastStickyBody(0, COL1) : stickyBody(0, COL1)), borderLeft: `1px solid ${bc}` }}>
                        <div className="font-medium">{row.equipment.equipmentCode}</div>
                        <div className="text-muted-foreground">{row.equipment.name}</div>
                      </td>
                      <td className="p-1.5 text-center text-muted-foreground" colSpan={2 + gridData.labels.length + 1} style={{ borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}` }}>
                        점검항목 없음
                      </td>
                    </tr>
                  ) : (
                    row.templates.map((template, tIdx) => (
                      <tr key={`${row.equipment.id}-${template.id}`}>
                        {tIdx === 0 && (
                          <td
                            className="p-1.5"
                            rowSpan={row.templates.length}
                            style={{ ...(isMobile ? lastStickyBody(0, COL1) : stickyBody(0, COL1)), borderLeft: `1px solid ${bc}` }}
                          >
                            <div className="font-medium">{row.equipment.equipmentCode}</div>
                            <div className="text-muted-foreground">{row.equipment.name}</div>
                          </td>
                        )}
                        <td className="p-1.5" style={isMobile ? normalBody(COL2) : stickyBody(COL1, COL2)}>{template.checkPoint}</td>
                        <td className="p-1.5" style={isMobile ? normalBody(COL3) : lastStickyBody(COL1 + COL2, COL3)}>{template.checkItem}</td>
                        {gridData.labels.map((label) => {
                          const key = `${template.id}_${label}`;
                          const result = row.details[key];
                          const isNonWorking = gridData.nonWorkingDays.includes(label);
                          return (
                            <td
                              key={label}
                              className={`p-0 text-center cursor-pointer hover:bg-blue-50 transition-colors ${getResultColor(result)}`}
                              style={{
                                borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}`,
                                ...(isNonWorking ? { background: '#fef2f2' } : {}),
                              }}
                              onClick={() => {
                                if (!row.canInspect) {
                                  toast.error('담당자만 점검을 입력할 수 있습니다.');
                                  return;
                                }
                                handleCellClick(row.equipment.id, template.id, label);
                              }}
                            >
                              <span className="text-sm font-bold">{getResultSymbol(result)}</span>
                            </td>
                          );
                        })}
                        {tIdx === 0 && (
                          <td
                            className="p-1.5 text-center font-bold"
                            rowSpan={row.templates.length}
                            style={{ borderRight: `1px solid ${bc}`, borderBottom: `1px solid ${bc}` }}
                          >
                            {row.overallJudgment || '-'}
                          </td>
                        )}
                      </tr>
                    ))
                  )
                )}
              </tbody>
            </table>
            </div>
              );
            })()}

            {/* 범례 */}
            <div className="flex items-center gap-4 mt-4 text-xs text-muted-foreground">
              <span className="flex items-center gap-1">
                <span className="text-green-600 font-bold">○</span> 양호
              </span>
              <span className="flex items-center gap-1">
                <span className="text-red-600 font-bold">X</span> 불량
              </span>
              <span className="flex items-center gap-1">
                <span className="text-yellow-600 font-bold">△</span> 수리
              </span>
              <span className="flex items-center gap-1">
                <span className="inline-block w-3 h-3 bg-red-50 border"></span> 휴일
              </span>
            </div>
          </CardContent>
        </Card>
      )}

      {/* 전체 초기화 확인 */}
      <ConfirmDialog
        open={showReset}
        onOpenChange={setShowReset}
        title="점검 데이터 전체 초기화"
        description={`${period} ${INSPECTION_CYCLE_LABEL[cycle]} 점검 데이터를 모두 초기화하시겠습니까? 이 작업은 되돌릴 수 없습니다.`}
        confirmText="전체 초기화"
        variant="destructive"
        onConfirm={handleReset}
      />
    </div>
  );
}
