import { useState, useCallback, useEffect } from "react";
import { toast } from "sonner";
import PageHeader from "@/components/common/PageHeader";
import SearchInput from "@/components/common/SearchInput";
import FilterDropdown from "@/components/common/FilterDropdown";
import FilterResetButton from "@/components/common/FilterResetButton";
import Pagination from "@/components/common/Pagination";
import EmptyState from "@/components/common/EmptyState";
import PlatformBadge from "@/components/common/PlatformBadge";
import SecretToggleCell from "../components/SecretToggleCell";
import DeviceSlidePanel from "../components/DeviceSlidePanel";
import { formatDate } from "@/utils/format";
import { fetchDevices, exportDevices } from "@/api/device.api";
import { fetchServices } from "@/api/service.api";
import {
  PLATFORM_FILTER_OPTIONS,
  PUSH_CONSENT_FILTER_OPTIONS,
} from "../types";
import type { DeviceListItem } from "../types";

const PAGE_SIZE = 10;

// 테이블 컬럼 헤더
const COLUMNS = [
  "소속 서비스",
  "플랫폼",
  "Device ID",
  "Push Token",
  "푸시 수신",
  "광고 수신",
  "태그",
  "등록일",
];

export default function DeviceListPage() {
  // 필터 입력 상태
  const [search, setSearch] = useState("");
  const [serviceFilter, setServiceFilter] = useState("전체 서비스");
  const [platformFilter, setPlatformFilter] = useState("전체");
  const [pushFilter, setPushFilter] = useState("전체");
  const [currentPage, setCurrentPage] = useState(1);
  const [loading, setLoading] = useState(false);

  // 적용된 필터
  const [appliedSearch, setAppliedSearch] = useState("");
  const [appliedService, setAppliedService] = useState("전체 서비스");
  const [appliedPlatform, setAppliedPlatform] = useState("전체");
  const [appliedPush, setAppliedPush] = useState("전체");

  // 서비스 목록 (API에서 로드)
  const [serviceFilterOptions, setServiceFilterOptions] = useState<string[]>([
    "전체 서비스",
  ]);
  const [serviceCodeMap, setServiceCodeMap] = useState<
    Record<string, string>
  >({});

  // 데이터
  const [items, setItems] = useState<DeviceListItem[]>([]);
  const [totalItems, setTotalItems] = useState(0);
  const [totalPages, setTotalPages] = useState(1);

  // 슬라이드 패널
  const [panelOpen, setPanelOpen] = useState(false);
  const [selectedDevice, setSelectedDevice] = useState<DeviceListItem | null>(
    null,
  );

  // SecretToggleCell 배타적 관리
  const [openDropdownKey, setOpenDropdownKey] = useState<string | null>(null);

  // 서비스 목록 로드 (초기화 시 1회)
  useEffect(() => {
    (async () => {
      try {
        const res = await fetchServices({ page: 1, pageSize: 100 });
        const svcItems = res.data.data.items ?? [];
        const names = svcItems.map((s) => s.serviceName);
        setServiceFilterOptions(["전체 서비스", ...names]);
        const codeMap: Record<string, string> = {};
        svcItems.forEach((s) => {
          codeMap[s.serviceName] = s.serviceCode;
        });
        setServiceCodeMap(codeMap);
      } catch {
        // 서비스 목록 로드 실패 시 기본값 유지
      }
    })();
  }, []);

  // 데이터 로드
  const loadData = useCallback(
    async (
      page: number,
      keyword: string,
      serviceName: string,
      platform: string,
      push: string,
    ) => {
      setLoading(true);
      try {
        const serviceCode =
          serviceName !== "전체 서비스"
            ? serviceCodeMap[serviceName] || undefined
            : undefined;

        const res = await fetchDevices(
          {
            page,
            size: PAGE_SIZE,
            keyword: keyword || undefined,
            platform: platform !== "전체" ? platform : undefined,
            push_agreed:
              push === "동의" ? true : push === "미동의" ? false : undefined,
          },
          serviceCode,
        );

        const data = res.data.data;
        setItems(data.items ?? []);
        setTotalItems(data.totalCount ?? 0);
        setTotalPages(data.totalPages ?? 1);
      } catch {
        setItems([]);
        setTotalItems(0);
        setTotalPages(1);
      } finally {
        setLoading(false);
      }
    },
    [serviceCodeMap],
  );

  // 초기 로드
  useEffect(() => {
    loadData(1, "", "전체 서비스", "전체", "전체");
  }, [loadData]);

  // 조회
  const handleQuery = () => {
    setAppliedSearch(search);
    setAppliedService(serviceFilter);
    setAppliedPlatform(platformFilter);
    setAppliedPush(pushFilter);
    setCurrentPage(1);
    loadData(1, search, serviceFilter, platformFilter, pushFilter);
  };

  // 필터 초기화
  const handleReset = () => {
    setSearch("");
    setServiceFilter("전체 서비스");
    setPlatformFilter("전체");
    setPushFilter("전체");
    setAppliedSearch("");
    setAppliedService("전체 서비스");
    setAppliedPlatform("전체");
    setAppliedPush("전체");
    setCurrentPage(1);
    loadData(1, "", "전체 서비스", "전체", "전체");
  };

  // 페이지 변경
  const handlePageChange = (page: number) => {
    setCurrentPage(page);
    loadData(page, appliedSearch, appliedService, appliedPlatform, appliedPush);
  };

  // 행 클릭
  const handleRowClick = (device: DeviceListItem) => {
    setOpenDropdownKey(null);
    setSelectedDevice(device);
    setPanelOpen(true);
  };

  // 패널 닫기 (삭제 후 목록 새로고침)
  const handlePanelClose = () => {
    setPanelOpen(false);
    loadData(
      currentPage,
      appliedSearch,
      appliedService,
      appliedPlatform,
      appliedPush,
    );
  };

  // 엑셀 내보내기
  const handleExport = async () => {
    if (appliedService === "전체 서비스") {
      toast.error("엑셀 다운로드를 위해 서비스를 선택해주세요.");
      return;
    }
    const serviceCode = serviceCodeMap[appliedService];
    if (!serviceCode) return;

    try {
      const res = await exportDevices(
        {
          keyword: appliedSearch || undefined,
          platform:
            appliedPlatform !== "전체" ? appliedPlatform : undefined,
          push_agreed:
            appliedPush === "동의"
              ? true
              : appliedPush === "미동의"
                ? false
                : undefined,
        },
        serviceCode,
      );

      const blob = new Blob([res.data], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `devices_${new Date().toISOString().split("T")[0]}.xlsx`;
      a.click();
      window.URL.revokeObjectURL(url);
    } catch {
      toast.error("엑셀 다운로드에 실패했습니다.");
    }
  };

  // 체크/취소 아이콘
  const StatusIcon = ({ active }: { active: boolean }) => (
    <span
      className={`material-symbols-outlined ${active ? "text-green-500" : "text-red-400"}`}
      style={{ fontSize: "20px" }}
    >
      {active ? "check_circle" : "cancel"}
    </span>
  );

  // 태그 아이콘 (있으면 체크, 없으면 dash)
  const TagIcon = ({ hasTags }: { hasTags: boolean }) =>
    hasTags ? (
      <span
        className="material-symbols-outlined text-green-500"
        style={{ fontSize: "20px" }}
      >
        check_circle
      </span>
    ) : (
      <span
        className="material-symbols-outlined text-red-400"
        style={{ fontSize: "20px" }}
      >
        cancel
      </span>
    );

  // 테이블 헤더 렌더링
  const renderTableHead = () => (
    <thead className="bg-gray-50 border-b border-gray-200">
      <tr>
        {COLUMNS.map((col) => (
          <th
            key={col}
            className={`px-6 py-4 text-xs font-semibold uppercase text-gray-700 text-center ${
              ["푸시 수신", "광고 수신", "태그"].includes(col)
                ? "w-[100px] whitespace-nowrap"
                : ""
            }`}
          >
            {col}
          </th>
        ))}
      </tr>
    </thead>
  );

  return (
    <div>
      <PageHeader
        title="기기 관리"
        description="등록된 디바이스 현황을 조회하고 관리할 수 있습니다."
        action={
          <button
            onClick={handleExport}
            className="flex items-center justify-center gap-2 min-w-[154px] px-5 py-2.5 bg-white border border-gray-300 hover:bg-gray-50 text-[#0f172a] rounded-lg text-sm font-medium transition-colors"
          >
            <span className="material-symbols-outlined text-lg">download</span>
            엑셀 다운로드
          </button>
        }
      />

      {/* 필터바 */}
      <div className="bg-white border border-gray-200 rounded-lg p-6 mb-6">
        <div className="flex flex-wrap items-end gap-4">
          <SearchInput
            value={search}
            onChange={setSearch}
            placeholder="Device ID 또는 Push Token 검색"
            label="검색어"
            disabled={loading}
          />
          <FilterDropdown
            label="서비스"
            value={serviceFilter}
            options={serviceFilterOptions}
            onChange={setServiceFilter}
            className="w-[140px] flex-shrink-0"
            disabled={loading}
          />
          <FilterDropdown
            label="플랫폼"
            value={platformFilter}
            options={PLATFORM_FILTER_OPTIONS}
            onChange={setPlatformFilter}
            className="w-[120px] flex-shrink-0"
            disabled={loading}
          />
          <FilterDropdown
            label="푸시 수신"
            value={pushFilter}
            options={PUSH_CONSENT_FILTER_OPTIONS}
            onChange={setPushFilter}
            className="w-[120px] flex-shrink-0"
            disabled={loading}
          />
          <FilterResetButton onClick={handleReset} disabled={loading} />
          <button
            onClick={handleQuery}
            disabled={loading}
            className="h-[38px] flex-shrink-0 bg-gray-800 hover:bg-gray-900 active:scale-95 text-white rounded-lg px-5 text-sm font-medium transition-all disabled:opacity-50 disabled:cursor-not-allowed"
          >
            조회
          </button>
        </div>
      </div>

      {/* 테이블 */}
      {loading ? (
        /* 로딩 스켈레톤 */
        <div className="bg-white border border-gray-200 rounded-lg overflow-hidden shadow-sm">
          <table className="w-full text-sm">
            {renderTableHead()}
            <tbody>
              {Array.from({ length: 5 }).map((_, i) => (
                <tr
                  key={i}
                  className={i < 4 ? "border-b border-gray-100" : ""}
                >
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-20 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-14 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-16 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-16 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-6 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-6 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-6 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                  <td className="px-6 py-4 text-center">
                    <div className="h-4 w-20 rounded bg-gray-100 animate-pulse mx-auto" />
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      ) : items.length > 0 ? (
        <div className="bg-white border border-gray-200 rounded-lg overflow-hidden shadow-sm">
          <div className="overflow-x-auto">
            <table className="w-full">
              {renderTableHead()}
              <tbody>
                {items.map((device, idx) => (
                  <tr
                    key={device.device_id}
                    className={`${idx < items.length - 1 ? "border-b border-gray-100" : ""} hover:bg-gray-50/50 transition-colors cursor-pointer`}
                    onClick={() => handleRowClick(device)}
                  >
                    {/* 소속 서비스 */}
                    <td className="px-6 py-4 text-center">
                      <span className="text-sm text-gray-700">
                        {device.service_name}
                      </span>
                    </td>
                    {/* 플랫폼 */}
                    <td className="px-6 py-4 text-center">
                      <PlatformBadge
                        platform={
                          device.platform === "iOS" ? "ios" : "android"
                        }
                      />
                    </td>
                    {/* Device ID */}
                    <td className="px-6 py-4 text-center">
                      <SecretToggleCell
                        label="ID 확인"
                        value={String(device.device_id)}
                        dropdownKey={`${device.device_id}-id`}
                        openKey={openDropdownKey}
                        onToggle={setOpenDropdownKey}
                      />
                    </td>
                    {/* Push Token */}
                    <td className="px-6 py-4 text-center">
                      <SecretToggleCell
                        label="토큰 확인"
                        value={device.device_token ?? ""}
                        dropdownKey={`${device.device_id}-token`}
                        openKey={openDropdownKey}
                        onToggle={setOpenDropdownKey}
                      />
                    </td>
                    {/* 푸시 수신 */}
                    <td className="px-6 py-4 text-center">
                      <StatusIcon active={device.push_agreed} />
                    </td>
                    {/* 광고 수신 */}
                    <td className="px-6 py-4 text-center">
                      <StatusIcon active={device.marketing_agreed} />
                    </td>
                    {/* 태그 */}
                    <td className="px-6 py-4 text-center">
                      <TagIcon hasTags={(device.tags?.length ?? 0) > 0} />
                    </td>
                    {/* 등록일 */}
                    <td className="px-6 py-4 text-center">
                      <span className="text-sm text-gray-500">
                        {formatDate(device.created_at ?? "")}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          {/* 페이지네이션 */}
          <Pagination
            currentPage={currentPage}
            totalPages={totalPages}
            totalItems={totalItems}
            pageSize={PAGE_SIZE}
            onPageChange={handlePageChange}
          />
        </div>
      ) : (
        <EmptyState
          icon="search_off"
          message="검색 결과가 없습니다"
          description="다른 검색어를 입력하거나 필터를 변경해보세요."
        />
      )}

      {/* 슬라이드 패널 */}
      <DeviceSlidePanel
        isOpen={panelOpen}
        onClose={handlePanelClose}
        device={selectedDevice}
        serviceCode={
          selectedDevice?.service_code ??
          (appliedService !== "전체 서비스"
            ? serviceCodeMap[appliedService]
            : undefined)
        }
      />
    </div>
  );
}
