'use client';

import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
import { Search as SearchIcon } from 'lucide-react';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Input } from '@/components/ui/input';
import { DateRangeSelector } from '@/components/molecules/DateRangeSelector';
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  ResponsiveContainer,
  PieChart,
  Pie,
  Cell,
} from 'recharts';
import { cn } from '@/lib/utils';
import { formatNumber as formatCurrency } from '@/lib/utils/amount';
import type {
  DateFilterConfig,
  PeriodSelectConfig,
  SummaryCardData,
  BarChartConfig,
  PieChartConfig,
  HorizontalBarChartConfig,
  TableConfig,
  ComparisonSectionConfig,
  ReferenceTableConfig,
  CalculationCardsConfig,
  QuarterlyTableConfig,
  ReviewCardsConfig,
} from '../types';

// ============================================
// 공통 유틸리티
// ============================================
// 필터 섹션
// ============================================

export const DateFilterSection = ({ config, onFilterChange }: { config: DateFilterConfig; onFilterChange?: (params: { startDate: string; endDate: string; search: string }) => void }) => {
  const today = new Date();
  const [startDate, setStartDate] = useState(() => {
    const d = new Date(today.getFullYear(), today.getMonth(), 1);
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
  });
  const [endDate, setEndDate] = useState(() => {
    const d = new Date(today.getFullYear(), today.getMonth() + 1, 0);
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
  });
  const [searchText, setSearchText] = useState('');
  const isInitialMount = useRef(true);

  // 날짜 변경 시 자동 조회 (다른 페이지와 동일한 UX)
  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;
      return;
    }
    onFilterChange?.({ startDate, endDate, search: searchText });
  }, [startDate, endDate]);

  const handleSearch = useCallback(() => {
    onFilterChange?.({ startDate, endDate, search: searchText });
  }, [startDate, endDate, searchText, onFilterChange]);

  const handleSearchKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Enter') handleSearch();
  }, [handleSearch]);

  return (
    <div className="pb-4 border-b">
      <DateRangeSelector
        startDate={startDate}
        endDate={endDate}
        onStartDateChange={setStartDate}
        onEndDateChange={setEndDate}
        extraActions={
          <div className="flex items-center gap-2 ml-auto">
            {config.showSearch !== false && (
              <div className="relative">
                <SearchIcon className="absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-gray-400" />
                <Input
                  value={searchText}
                  onChange={(e) => setSearchText(e.target.value)}
                  onKeyDown={handleSearchKeyDown}
                  placeholder="검색"
                  className="h-8 pl-7 pr-3 text-xs w-[140px]"
                />
              </div>
            )}
          </div>
        }
      />
    </div>
  );
};

export const PeriodSelectSection = ({ config }: { config: PeriodSelectConfig }) => {
  const [selected, setSelected] = useState(config.defaultValue || config.options[0]?.value || '');

  const handleChange = useCallback((value: string) => {
    setSelected(value);
    config.onPeriodChange?.(value);
  }, [config]);

  return (
    <div className="flex items-center gap-2 pb-4 border-b">
      <span className="text-sm text-gray-600 font-medium">신고기간</span>
      <Select value={selected} onValueChange={handleChange}>
        <SelectTrigger className="h-8 w-auto min-w-[200px] text-xs">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          {config.options.map((option) => (
            <SelectItem key={option.value} value={option.value}>
              {option.label}
            </SelectItem>
          ))}
        </SelectContent>
      </Select>
    </div>
  );
};

// ============================================
// 카드 섹션
// ============================================

export const SummaryCard = ({ data }: { data: SummaryCardData }) => {
  const displayValue = typeof data.value === 'number'
    ? formatCurrency(data.value) + (data.unit || '원')
    : data.value;

  return (
    <div className="bg-gray-50 rounded-lg p-3 sm:p-4">
      <p className="text-xs sm:text-sm text-gray-500 mb-1">{data.label}</p>
      <p className={cn(
        "text-lg sm:text-2xl font-bold break-all",
        data.isComparison && (data.isPositive ? "text-blue-600" : "text-red-600")
      )}>
        {data.isComparison && !data.isPositive && typeof data.value === 'string' && !data.value.startsWith('-') ? '-' : ''}
        {displayValue}
      </p>
    </div>
  );
};

export const ReviewCardsSection = ({ config }: { config: ReviewCardsConfig }) => {
  return (
    <div>
      <h4 className="font-medium text-gray-800 mb-3">{config.title}</h4>
      <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3">
        {config.cards.map((card, index) => (
          <div
            key={index}
            className="bg-orange-50 border border-orange-200 rounded-lg p-3 sm:p-4"
          >
            <p className="text-xs sm:text-sm text-orange-700 font-medium mb-1">{card.label}</p>
            <p className="text-lg sm:text-xl font-bold text-orange-900">
              {formatCurrency(card.amount)}원
            </p>
            <p className="text-xs text-orange-600 mt-1">{card.subLabel}</p>
          </div>
        ))}
      </div>
    </div>
  );
};

export const CalculationCardsSection = ({ config }: { config: CalculationCardsConfig }) => {
  const isResultCard = (_index: number, operator?: string) => {
    return operator === '=';
  };

  return (
    <div className="mt-6">
      <div className="flex items-center gap-2 mb-3">
        <h4 className="font-medium text-gray-800">{config.title}</h4>
        {config.subtitle && (
          <span className="text-sm text-gray-500">{config.subtitle}</span>
        )}
      </div>
      <div className="flex items-center gap-3">
        {config.cards.map((card, index) => (
          <div key={index} className="flex items-center gap-3">
            {index > 0 && card.operator && (
              <span className="text-3xl font-bold text-gray-400">
                {card.operator}
              </span>
            )}
            <div className={cn(
              "rounded-lg p-5 min-w-[180px] text-center border",
              isResultCard(index, card.operator)
                ? "bg-blue-50 border-blue-200"
                : "bg-gray-50 border-gray-200"
            )}>
              <p className={cn(
                "text-sm mb-2",
                isResultCard(index, card.operator) ? "text-blue-600" : "text-gray-500"
              )}>
                {card.label}
              </p>
              <p className={cn(
                "text-2xl font-bold",
                isResultCard(index, card.operator) ? "text-blue-700" : "text-gray-900"
              )}>
                {formatCurrency(card.value)}{card.unit || '원'}
              </p>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

// ============================================
// 차트 섹션
// ============================================

export const BarChartSection = ({ config }: { config: BarChartConfig }) => {
  return (
    <div className="bg-gray-50 rounded-lg p-3 sm:p-4">
      <p className="text-sm font-medium text-gray-700 mb-4">{config.title}</p>
      <div className="h-[150px]">
        <ResponsiveContainer width="100%" height="100%">
          <BarChart data={config.data} margin={{ top: 5, right: 5, left: -25, bottom: 5 }}>
            <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#E5E7EB" />
            <XAxis
              dataKey={config.xAxisKey}
              axisLine={false}
              tickLine={false}
              tick={{ fontSize: 10, fill: '#6B7280' }}
              interval={0}
            />
            <YAxis
              axisLine={false}
              tickLine={false}
              tick={{ fontSize: 9, fill: '#6B7280' }}
              tickFormatter={(value) => value >= 10000 ? `${value / 10000}만` : value}
              width={35}
            />
            <Tooltip
              formatter={(value) => [formatCurrency(value as number) + '원', '']}
              contentStyle={{ fontSize: 12 }}
            />
            <Bar
              dataKey={config.dataKey}
              fill={config.color || '#60A5FA'}
              radius={[4, 4, 0, 0]}
              maxBarSize={30}
            />
          </BarChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
};

export const PieChartSection = ({ config }: { config: PieChartConfig }) => {
  return (
    <div className="bg-gray-50 rounded-lg p-3 sm:p-4 overflow-hidden">
      <p className="text-sm font-medium text-gray-700 mb-4">{config.title}</p>
      <div className="flex justify-center mb-4">
        <PieChart width={100} height={100}>
          <Pie
            data={config.data as unknown as Array<Record<string, unknown>>}
            cx={50}
            cy={50}
            innerRadius={28}
            outerRadius={45}
            paddingAngle={2}
            dataKey="value"
          >
            {config.data.map((entry, index) => (
              <Cell key={`cell-${index}`} fill={entry.color} />
            ))}
          </Pie>
        </PieChart>
      </div>
      <div className="space-y-2">
        {config.data.map((item, index) => (
          <div key={index} className="flex items-center justify-between text-xs sm:text-sm gap-2">
            <div className="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-shrink">
              <div
                className="w-2.5 h-2.5 sm:w-3 sm:h-3 rounded-full flex-shrink-0"
                style={{ backgroundColor: item.color }}
              />
              <span className="text-gray-600 truncate">{item.name}</span>
              <span className="text-gray-400 flex-shrink-0">{item.percentage}%</span>
            </div>
            <span className="font-medium text-gray-900 flex-shrink-0">
              {formatCurrency(item.value)}원
            </span>
          </div>
        ))}
      </div>
    </div>
  );
};

export const HorizontalBarChartSection = ({ config }: { config: HorizontalBarChartConfig }) => {
  const maxValue = Math.max(...config.data.map(d => d.value));

  return (
    <div className="bg-gray-50 rounded-lg p-4">
      <p className="text-sm font-medium text-gray-700 mb-4">{config.title}</p>
      <div className="space-y-3">
        {config.data.map((item, index) => (
          <div key={index} className="space-y-1">
            <div className="flex items-center justify-between text-sm">
              <span className="text-gray-600">{item.name}</span>
              <span className="font-medium text-gray-900">
                {formatCurrency(item.value)}원
              </span>
            </div>
            <div className="h-4 bg-gray-200 rounded-full overflow-hidden">
              <div
                className="h-full rounded-full transition-all duration-300"
                style={{
                  width: `${(item.value / maxValue) * 100}%`,
                  backgroundColor: config.color || '#60A5FA',
                }}
              />
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

// ============================================
// 비교 섹션
// ============================================

export const ComparisonSection = ({ config }: { config: ComparisonSectionConfig }) => {
  const formatValue = (value: string | number, unit?: string): string => {
    if (typeof value === 'number') {
      return formatCurrency(value) + (unit || '원');
    }
    return value;
  };

  const borderColorClass = {
    orange: 'border-orange-400',
    blue: 'border-blue-400',
  };

  const titleBgClass = {
    orange: 'bg-orange-50',
    blue: 'bg-blue-50',
  };

  return (
    <div className="flex items-stretch gap-4">
      {/* 왼쪽 박스 */}
      <div className={cn(
        "flex-1 border-2 rounded-lg overflow-hidden",
        borderColorClass[config.leftBox.borderColor]
      )}>
        <div className={cn(
          "px-4 py-2 text-sm font-medium text-gray-700",
          titleBgClass[config.leftBox.borderColor]
        )}>
          {config.leftBox.title}
        </div>
        <div className="p-4 space-y-3">
          {config.leftBox.items.map((item, index) => (
            <div key={index}>
              <p className="text-xs text-gray-500 mb-1">{item.label}</p>
              <p className="text-lg font-bold text-gray-900">
                {formatValue(item.value, item.unit)}
              </p>
            </div>
          ))}
        </div>
      </div>

      {/* VS 영역 */}
      <div className="flex flex-col items-center justify-center px-4">
        <span className="text-2xl font-bold text-gray-400 mb-2">VS</span>
        <div className="bg-red-50 rounded-lg px-4 py-3 text-center min-w-[180px]">
          <p className="text-xs text-gray-600 mb-1">{config.vsLabel}</p>
          <p className="text-xl font-bold text-red-500">
            {typeof config.vsValue === 'number'
              ? formatCurrency(config.vsValue) + '원'
              : config.vsValue}
          </p>
          {config.vsSubLabel && (
            <p className="text-xs text-gray-500 mt-1">{config.vsSubLabel}</p>
          )}
          {config.vsBreakdown && config.vsBreakdown.length > 0 && (
            <div className="mt-2 pt-2 border-t border-red-200 space-y-1">
              {config.vsBreakdown.map((item, index) => (
                <div key={index} className="flex justify-between text-xs">
                  <span className="text-gray-600">{item.label}</span>
                  <span className="font-medium text-gray-700">
                    {typeof item.value === 'number'
                      ? formatCurrency(item.value) + (item.unit || '원')
                      : item.value}
                  </span>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* 오른쪽 박스 */}
      <div className={cn(
        "flex-1 border-2 rounded-lg overflow-hidden",
        borderColorClass[config.rightBox.borderColor]
      )}>
        <div className={cn(
          "px-4 py-2 text-sm font-medium text-gray-700",
          titleBgClass[config.rightBox.borderColor]
        )}>
          {config.rightBox.title}
        </div>
        <div className="p-4 space-y-3">
          {config.rightBox.items.map((item, index) => (
            <div key={index}>
              <p className="text-xs text-gray-500 mb-1">{item.label}</p>
              <p className="text-lg font-bold text-gray-900">
                {formatValue(item.value, item.unit)}
              </p>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// ============================================
// 테이블 섹션
// ============================================

export const QuarterlyTableSection = ({ config }: { config: QuarterlyTableConfig }) => {
  const formatValue = (value: number | string | undefined): string => {
    if (value === undefined) return '-';
    if (typeof value === 'number') return formatCurrency(value);
    return value;
  };

  return (
    <div className="mt-6">
      <h4 className="font-medium text-gray-800 mb-3">{config.title}</h4>
      <div className="border rounded-lg overflow-auto">
        <table className="w-full min-w-[500px]">
          <thead>
            <tr className="bg-gray-100">
              <th className="px-4 py-3 text-xs font-medium text-gray-600 text-left">구분</th>
              <th className="px-4 py-3 text-xs font-medium text-gray-600 text-center">1사분기</th>
              <th className="px-4 py-3 text-xs font-medium text-gray-600 text-center">2사분기</th>
              <th className="px-4 py-3 text-xs font-medium text-gray-600 text-center">3사분기</th>
              <th className="px-4 py-3 text-xs font-medium text-gray-600 text-center">4사분기</th>
              <th className="px-4 py-3 text-xs font-medium text-gray-600 text-center">합계</th>
            </tr>
          </thead>
          <tbody>
            {config.rows.map((row, rowIndex) => (
              <tr
                key={rowIndex}
                className="border-t border-gray-100 hover:bg-gray-50"
              >
                <td className="px-4 py-3 text-sm text-gray-700 font-medium">{row.label}</td>
                <td className="px-4 py-3 text-sm text-gray-700 text-center">{formatValue(row.q1)}</td>
                <td className="px-4 py-3 text-sm text-gray-700 text-center">{formatValue(row.q2)}</td>
                <td className="px-4 py-3 text-sm text-gray-700 text-center">{formatValue(row.q3)}</td>
                <td className="px-4 py-3 text-sm text-gray-700 text-center">{formatValue(row.q4)}</td>
                <td className="px-4 py-3 text-sm text-gray-900 text-center font-medium">{formatValue(row.total)}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

export const ReferenceTableSection = ({ config }: { config: ReferenceTableConfig }) => {
  const getAlignClass = (align?: string): string => {
    switch (align) {
      case 'center': return 'text-center';
      case 'right': return 'text-right';
      default: return 'text-left';
    }
  };

  return (
    <div className="mt-6">
      <h4 className="font-medium text-gray-800 mb-3">{config.title}</h4>
      <div className="border rounded-lg overflow-auto">
        <table className="w-full min-w-[400px]">
          <thead>
            <tr className="bg-gray-100">
              {config.columns.map((column) => (
                <th
                  key={column.key}
                  className={cn(
                    "px-4 py-3 text-xs font-medium text-gray-600",
                    getAlignClass(column.align)
                  )}
                >
                  {column.label}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {config.data.map((row, rowIndex) => (
              <tr
                key={rowIndex}
                className="border-t border-gray-100 hover:bg-gray-50"
              >
                {config.columns.map((column) => (
                  <td
                    key={column.key}
                    className={cn(
                      "px-4 py-3 text-sm text-gray-700",
                      getAlignClass(column.align)
                    )}
                  >
                    {String(row[column.key] ?? '-')}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

export const TableSection = ({ config, onRowClick }: { config: TableConfig; onRowClick?: (row: Record<string, unknown>) => void }) => {
  const [filters, setFilters] = useState<Record<string, string>>(() => {
    const initial: Record<string, string> = {};
    config.filters?.forEach((filter) => {
      initial[filter.key] = filter.defaultValue;
    });
    return initial;
  });

  const handleFilterChange = useCallback((key: string, value: string) => {
    setFilters((prev) => ({ ...prev, [key]: value }));
  }, []);

  const filteredData = useMemo(() => {
    if (!config.data || !Array.isArray(config.data)) {
      return [];
    }
    let result = [...config.data];

    config.filters?.forEach((filter) => {
      if (filter.key === 'sortOrder') return;
      const filterValue = filters[filter.key];
      if (filterValue && filterValue !== 'all') {
        result = result.filter((row) => row[filter.key] === filterValue);
      }
    });

    if (filters['sortOrder']) {
      const sortOrder = filters['sortOrder'];
      result.sort((a, b) => {
        if (sortOrder === 'amountDesc') {
          return (b['amount'] as number) - (a['amount'] as number);
        }
        if (sortOrder === 'amountAsc') {
          return (a['amount'] as number) - (b['amount'] as number);
        }
        const dateA = new Date(a['date'] as string).getTime();
        const dateB = new Date(b['date'] as string).getTime();
        return sortOrder === 'latest' ? dateB - dateA : dateA - dateB;
      });
    }

    return result;
  }, [config.data, config.filters, filters]);

  const formatCellValue = (value: unknown, format?: string): string => {
    if (value === null || value === undefined) return '-';
    switch (format) {
      case 'currency':
      case 'number':
        return typeof value === 'number' ? formatCurrency(value) : String(value);
      default:
        return String(value);
    }
  };

  const getAlignClass = (align?: string): string => {
    switch (align) {
      case 'center': return 'text-center';
      case 'right': return 'text-right';
      default: return 'text-left';
    }
  };

  return (
    <div className="mt-6">
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-center gap-2">
          <h4 className="font-medium text-gray-800">{config.title}</h4>
          <span className="text-sm text-gray-500">총 {filteredData.length}건</span>
        </div>

        {config.filters && config.filters.length > 0 && (
          <div className="flex items-center gap-2">
            {config.filters.map((filter) => (
              <Select
                key={filter.key}
                value={filters[filter.key]}
                onValueChange={(value) => handleFilterChange(filter.key, value)}
              >
                <SelectTrigger className="h-8 w-auto min-w-[80px] w-auto text-xs">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {filter.options.map((option) => (
                    <SelectItem key={option.value} value={option.value}>
                      {option.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            ))}
          </div>
        )}
      </div>

      <div className="border rounded-lg max-h-[400px] overflow-auto">
        <table className="w-full min-w-[600px]">
          <thead className="sticky top-0 z-10">
            <tr className="bg-gray-100">
              {config.columns.map((column) => (
                <th
                  key={column.key}
                  className={cn(
                    "px-4 py-3 text-xs font-medium text-gray-600",
                    getAlignClass(column.align),
                    column.width && `w-[${column.width}]`
                  )}
                >
                  {column.label}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {filteredData.map((row, rowIndex) => (
              <tr
                key={rowIndex}
                className={cn(
                  "border-t border-gray-100 hover:bg-gray-50",
                  onRowClick && "cursor-pointer hover:bg-blue-50"
                )}
                onClick={onRowClick ? () => onRowClick(row) : undefined}
              >
                {config.columns.map((column) => {
                  const cellValue = column.key === 'no'
                    ? rowIndex + 1
                    : formatCellValue(row[column.key], column.format);
                  const isHighlighted = column.highlightValue && String(row[column.key]) === column.highlightValue;

                  const highlightColorClass = column.highlightColor ? {
                    red: 'text-red-500',
                    orange: 'text-orange-500',
                    blue: 'text-blue-500',
                    green: 'text-green-500',
                  }[column.highlightColor] : '';

                  return (
                    <td
                      key={column.key}
                      className={cn(
                        "px-4 py-3 text-sm",
                        getAlignClass(column.align),
                        isHighlighted && "text-orange-500 font-medium",
                        highlightColorClass
                      )}
                    >
                      {cellValue}
                    </td>
                  );
                })}
              </tr>
            ))}

            {config.showTotal && (
              <tr className="border-t-2 border-gray-200 bg-gray-50 font-medium">
                {config.columns.map((column, colIndex) => (
                  <td
                    key={column.key}
                    className={cn(
                      "px-4 py-3 text-sm",
                      getAlignClass(column.align)
                    )}
                  >
                    {column.key === config.totalColumnKey
                      ? (typeof config.totalValue === 'number'
                          ? formatCurrency(config.totalValue)
                          : config.totalValue)
                      : (colIndex === 0 ? config.totalLabel || '합계' : '')}
                  </td>
                ))}
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {config.footerSummary && config.footerSummary.length > 0 && (
        <div className="mt-4 border rounded-lg bg-gray-50 p-4">
          <div className="space-y-2">
            {config.footerSummary.map((item, index) => (
              <div key={index} className="flex items-center justify-between">
                <span className="text-sm text-gray-600">{item.label}</span>
                <span className="font-medium text-gray-900">
                  {typeof item.value === 'number'
                    ? formatCurrency(item.value)
                    : item.value}
                </span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};
