"use client";

import React, { useState, useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { ArrowLeft, Save, RefreshCw, ArrowRight, Trash2 } from "lucide-react";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { useRouter } from "next/navigation";
import {
  BatchAPI,
  BatchMapping,
  ConnectionInfo,
  ColumnInfo,
  BatchMappingRequest,
} from "@/lib/api/batch";

export default function BatchCreatePage() {
  const router = useRouter();
  
  // 기본 정보
  const [batchName, setBatchName] = useState("");
  const [cronSchedule, setCronSchedule] = useState("0 12 * * *");
  const [description, setDescription] = useState("");
  
  // 커넥션 및 데이터
  const [connections, setConnections] = useState<ConnectionInfo[]>([]);
  const [fromConnection, setFromConnection] = useState<ConnectionInfo | null>(null);
  const [toConnection, setToConnection] = useState<ConnectionInfo | null>(null);
  const [fromTables, setFromTables] = useState<string[]>([]);
  const [toTables, setToTables] = useState<string[]>([]);
  const [fromTable, setFromTable] = useState("");
  const [toTable, setToTable] = useState("");
  const [fromColumns, setFromColumns] = useState<ColumnInfo[]>([]);
  const [toColumns, setToColumns] = useState<ColumnInfo[]>([]);
  
  // 매핑 상태
  const [selectedFromColumn, setSelectedFromColumn] = useState<ColumnInfo | null>(null);
  const [mappings, setMappings] = useState<BatchMapping[]>([]);
  
  // 로딩 상태
  const [loading, setLoading] = useState(false);
  const [loadingConnections, setLoadingConnections] = useState(false);

  // 커넥션 목록 로드
  useEffect(() => {
    loadConnections();
  }, []);

  const loadConnections = async () => {
    setLoadingConnections(true);
    try {
      const data = await BatchAPI.getConnections();
      setConnections(Array.isArray(data) ? data : []);
    } catch (error) {
      console.error("커넥션 로드 실패:", error);
      toast.error("커넥션 목록을 불러오는데 실패했습니다.");
      setConnections([]);
    } finally {
      setLoadingConnections(false);
    }
  };

  // FROM 커넥션 변경
  const handleFromConnectionChange = async (connectionId: string) => {
    if (connectionId === 'unknown') return;
    
    const connection = connections.find(conn => {
      if (conn.type === 'internal') {
        return connectionId === 'internal';
      }
      return conn.id ? conn.id.toString() === connectionId : false;
    });
    
    if (!connection) return;
    
    setFromConnection(connection);
    setFromTable("");
    setFromTables([]);
    setFromColumns([]);
    setSelectedFromColumn(null);
    
    try {
      const tables = await BatchAPI.getTablesFromConnection(connection);
      setFromTables(Array.isArray(tables) ? tables : []);
    } catch (error) {
      console.error("FROM 테이블 목록 로드 실패:", error);
      toast.error("테이블 목록을 불러오는데 실패했습니다.");
    }
  };

  // TO 커넥션 변경
  const handleToConnectionChange = async (connectionId: string) => {
    if (connectionId === 'unknown') return;
    
    const connection = connections.find(conn => {
      if (conn.type === 'internal') {
        return connectionId === 'internal';
      }
      return conn.id ? conn.id.toString() === connectionId : false;
    });
    
    if (!connection) return;
    
    setToConnection(connection);
    setToTable("");
    setToTables([]);
    setToColumns([]);
    
    try {
      const tables = await BatchAPI.getTablesFromConnection(connection);
      setToTables(Array.isArray(tables) ? tables : []);
    } catch (error) {
      console.error("TO 테이블 목록 로드 실패:", error);
      toast.error("테이블 목록을 불러오는데 실패했습니다.");
    }
  };

  // FROM 테이블 변경
  const handleFromTableChange = async (tableName: string) => {
    setFromTable(tableName);
    setFromColumns([]);
    setSelectedFromColumn(null);
    
    if (!fromConnection || !tableName) return;
    
    try {
      const columns = await BatchAPI.getTableColumns(fromConnection, tableName);
      setFromColumns(Array.isArray(columns) ? columns : []);
    } catch (error) {
      console.error("FROM 컬럼 목록 로드 실패:", error);
      showErrorToast("컬럼 목록을 불러오는 데 실패했습니다", error, { guidance: "테이블 정보를 확인해 주세요." });
    }
  };

  // TO 테이블 변경
  const handleToTableChange = async (tableName: string) => {
    setToTable(tableName);
    setToColumns([]);
    
    if (!toConnection || !tableName) return;
    
    try {
      const columns = await BatchAPI.getTableColumns(toConnection, tableName);
      setToColumns(Array.isArray(columns) ? columns : []);
    } catch (error) {
      console.error("TO 컬럼 목록 로드 실패:", error);
      toast.error("컬럼 목록을 불러오는데 실패했습니다.");
    }
  };

  // FROM 컬럼 선택
  const handleFromColumnClick = (column: ColumnInfo) => {
    setSelectedFromColumn(column);
    toast.info(`FROM 컬럼 선택됨: ${column.column_name}`);
  };

  // TO 컬럼 선택 (매핑 생성)
  const handleToColumnClick = (toColumn: ColumnInfo) => {
    if (!selectedFromColumn || !fromConnection || !toConnection) {
      toast.error("먼저 FROM 컬럼을 선택해주세요.");
      return;
    }

    // n:1 매핑 검사
    const toKey = `${toConnection.type}:${toConnection.id || 'internal'}:${toTable}:${toColumn.column_name}`;
    const existingMapping = mappings.find(mapping => {
      const existingToKey = `${mapping.to_connection_type}:${mapping.to_connection_id || 'internal'}:${mapping.to_table_name}:${mapping.to_column_name}`;
      return existingToKey === toKey;
    });

    if (existingMapping) {
      toast.error("동일한 TO 컬럼에 중복 매핑할 수 없습니다. (n:1 매핑 방지)");
      return;
    }

    const newMapping: BatchMapping = {
      from_connection_type: fromConnection.type,
      from_connection_id: fromConnection.id || null,
      from_table_name: fromTable,
      from_column_name: selectedFromColumn.column_name,
      from_column_type: selectedFromColumn.data_type || '',
      to_connection_type: toConnection.type,
      to_connection_id: toConnection.id || null,
      to_table_name: toTable,
      to_column_name: toColumn.column_name,
      to_column_type: toColumn.data_type || '',
      mapping_order: mappings.length + 1,
    };

    setMappings([...mappings, newMapping]);
    setSelectedFromColumn(null);
    toast.success(`매핑 생성: ${selectedFromColumn.column_name} → ${toColumn.column_name}`);
  };

  // 매핑 삭제
  const removeMapping = (index: number) => {
    const newMappings = mappings.filter((_, i) => i !== index);
    const reorderedMappings = newMappings.map((mapping, i) => ({
      ...mapping,
      mapping_order: i + 1
    }));
    setMappings(reorderedMappings);
    toast.success("매핑이 삭제되었습니다.");
  };

  // 배치 설정 저장
  const saveBatchConfig = async () => {
    if (!batchName.trim()) {
      toast.error("배치명을 입력해주세요.");
      return;
    }

    if (!cronSchedule.trim()) {
      toast.error("실행 스케줄을 입력해주세요.");
      return;
    }

    if (mappings.length === 0) {
      toast.error("최소 하나 이상의 매핑을 추가해주세요.");
      return;
    }

    setLoading(true);
    try {
      const request = {
        batchName: batchName,
        description: description || undefined,
        cronSchedule: cronSchedule,
        mappings: mappings,
        isActive: true
      };

      await BatchAPI.createBatchConfig(request);
      toast.success("배치 설정이 성공적으로 저장되었습니다!");
      
      // 목록 페이지로 이동
      router.push("/admin/batchmng");
    } catch (error) {
      console.error("배치 설정 저장 실패:", error);
      showErrorToast("배치 설정 저장에 실패했습니다", error, { guidance: "입력 데이터를 확인하고 다시 시도해 주세요." });
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="container mx-auto p-6 space-y-6">
      {/* 헤더 */}
      <div className="flex items-center justify-between">
        <div className="flex items-center space-x-4">
          <Button
            variant="outline"
            onClick={() => router.push("/admin/batchmng")}
            className="flex items-center space-x-2"
          >
            <ArrowLeft className="h-4 w-4" />
            <span>목록으로</span>
          </Button>
          <div>
            <h1 className="text-3xl font-bold">배치관리 매핑 시스템</h1>
            <p className="text-muted-foreground">새로운 배치 매핑을 생성합니다.</p>
          </div>
        </div>
      </div>

      {/* 기본 정보 */}
      <Card>
        <CardHeader>
          <CardTitle>기본 정보</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div className="space-y-2">
              <Label htmlFor="batchName">배치명 *</Label>
              <Input
                id="batchName"
                value={batchName}
                onChange={(e) => setBatchName(e.target.value)}
                placeholder="배치명을 입력하세요"
              />
            </div>
            <div className="space-y-2">
              <Label htmlFor="cronSchedule">실행 스케줄 (Cron) *</Label>
              <Input
                id="cronSchedule"
                value={cronSchedule}
                onChange={(e) => setCronSchedule(e.target.value)}
                placeholder="0 12 * * * (매일 12시)"
              />
            </div>
          </div>
          <div className="space-y-2">
            <Label htmlFor="description">설명</Label>
            <Textarea
              id="description"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="배치에 대한 설명을 입력하세요"
              rows={3}
            />
          </div>
        </CardContent>
      </Card>

      {/* 매핑 설정 */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        {/* FROM 섹션 */}
        <Card className="border-green-200">
          <CardHeader className="bg-green-50">
            <CardTitle className="text-green-700">FROM (원본 데이터베이스)</CardTitle>
            <p className="text-sm text-green-600">
              1단계: 커넥션을 선택하세요 → 2단계: 테이블을 선택하세요 → 3단계: 컬럼을 클릭해서 매핑하세요
            </p>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label>커넥션 선택</Label>
              <Select
                value={fromConnection?.type === 'internal' ? 'internal' : fromConnection?.id?.toString() || ""}
                onValueChange={handleFromConnectionChange}
                disabled={loadingConnections}
              >
                <SelectTrigger>
                  <SelectValue placeholder={loadingConnections ? "로딩 중..." : "커넥션을 선택하세요"} />
                </SelectTrigger>
                <SelectContent>
                  {Array.isArray(connections) && connections.map((conn) => (
                    <SelectItem 
                      key={conn.type === 'internal' ? 'internal' : conn.id?.toString() || conn.name} 
                      value={conn.type === 'internal' ? 'internal' : conn.id?.toString() || 'unknown'}
                    >
                      {conn.name} ({conn.type})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-2">
              <Label>테이블 선택</Label>
              <Select
                value={fromTable}
                onValueChange={handleFromTableChange}
                disabled={!fromConnection}
              >
                <SelectTrigger>
                  <SelectValue placeholder="테이블을 선택하세요" />
                </SelectTrigger>
                <SelectContent>
                  {fromTables.map((table) => (
                    <SelectItem key={table} value={table}>
                      {table}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            {/* FROM 컬럼 목록 */}
            {fromTable && (
              <div className="space-y-2">
                <Label className="text-blue-600 font-semibold">{fromTable} 테이블</Label>
                <div className="border rounded-lg p-4 max-h-80 overflow-y-auto space-y-2">
                  {fromColumns.map((column) => (
                    <div
                      key={column.column_name}
                      onClick={() => handleFromColumnClick(column)}
                      className={`p-3 border rounded cursor-pointer transition-colors ${
                        selectedFromColumn?.column_name === column.column_name
                          ? 'bg-green-100 border-green-300'
                          : 'hover:bg-gray-50 border-gray-200'
                      }`}
                    >
                      <div className="font-medium">{column.column_name}</div>
                      <div className="text-sm text-gray-500">{column.data_type}</div>
                    </div>
                  ))}
                  {fromColumns.length === 0 && fromTable && (
                    <div className="text-center text-gray-500 py-4">
                      컬럼을 불러오는 중...
                    </div>
                  )}
                </div>
              </div>
            )}
          </CardContent>
        </Card>

        {/* TO 섹션 */}
        <Card className="border-red-200">
          <CardHeader className="bg-red-50">
            <CardTitle className="text-red-700">TO (대상 데이터베이스)</CardTitle>
            <p className="text-sm text-red-600">
              FROM에서 컬럼을 선택한 후, 여기서 대상 컬럼을 클릭하면 매핑됩니다
            </p>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="space-y-2">
              <Label>커넥션 선택</Label>
              <Select
                value={toConnection?.type === 'internal' ? 'internal' : toConnection?.id?.toString() || ""}
                onValueChange={handleToConnectionChange}
                disabled={loadingConnections}
              >
                <SelectTrigger>
                  <SelectValue placeholder={loadingConnections ? "로딩 중..." : "커넥션을 선택하세요"} />
                </SelectTrigger>
                <SelectContent>
                  {Array.isArray(connections) && connections.map((conn) => (
                    <SelectItem 
                      key={conn.type === 'internal' ? 'internal' : conn.id?.toString() || conn.name} 
                      value={conn.type === 'internal' ? 'internal' : conn.id?.toString() || 'unknown'}
                    >
                      {conn.name} ({conn.type})
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-2">
              <Label>테이블 선택</Label>
              <Select
                value={toTable}
                onValueChange={handleToTableChange}
                disabled={!toConnection}
              >
                <SelectTrigger>
                  <SelectValue placeholder="테이블을 선택하세요" />
                </SelectTrigger>
                <SelectContent>
                  {toTables.map((table) => (
                    <SelectItem key={table} value={table}>
                      {table}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            {/* TO 컬럼 목록 */}
            {toTable && (
              <div className="space-y-2">
                <Label className="text-blue-600 font-semibold">{toTable} 테이블</Label>
                <div className="border rounded-lg p-4 max-h-80 overflow-y-auto space-y-2">
                  {toColumns.map((column) => (
                    <div
                      key={column.column_name}
                      onClick={() => handleToColumnClick(column)}
                      className={`p-3 border rounded cursor-pointer transition-colors ${
                        selectedFromColumn 
                          ? 'hover:bg-red-50 border-gray-200'
                          : 'bg-gray-100 border-gray-300 cursor-not-allowed'
                      }`}
                    >
                      <div className="font-medium">{column.column_name}</div>
                      <div className="text-sm text-gray-500">{column.data_type}</div>
                    </div>
                  ))}
                  {toColumns.length === 0 && toTable && (
                    <div className="text-center text-gray-500 py-4">
                      컬럼을 불러오는 중...
                    </div>
                  )}
                </div>
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      {/* 매핑 현황 */}
      {mappings.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle>컬럼 매핑 현황 ({mappings.length}개)</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="space-y-3">
              {mappings.map((mapping, index) => (
                <div key={index} className="flex items-center justify-between p-4 border rounded-lg bg-yellow-50">
                  <div className="flex items-center space-x-4">
                    <div className="text-sm">
                      <div className="font-medium">
                        {mapping.from_table_name}.{mapping.from_column_name}
                      </div>
                      <div className="text-gray-500">
                        {mapping.from_column_type}
                      </div>
                    </div>
                    <ArrowRight className="h-4 w-4 text-gray-400" />
                    <div className="text-sm">
                      <div className="font-medium">
                        {mapping.to_table_name}.{mapping.to_column_name}
                      </div>
                      <div className="text-gray-500">
                        {mapping.to_column_type}
                      </div>
                    </div>
                  </div>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => removeMapping(index)}
                    className="text-red-600 hover:text-red-700"
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </div>
              ))}
            </div>
          </CardContent>
        </Card>
      )}

      {/* 저장 버튼 */}
      <div className="flex justify-end space-x-4">
        <Button
          variant="outline"
          onClick={() => router.push("/admin/batchmng")}
        >
          취소
        </Button>
        <Button
          onClick={saveBatchConfig}
          disabled={loading || mappings.length === 0}
          className="flex items-center space-x-2"
        >
          {loading ? (
            <RefreshCw className="h-4 w-4 animate-spin" />
          ) : (
            <Save className="h-4 w-4" />
          )}
          <span>{loading ? "저장 중..." : "배치 매핑 저장"}</span>
        </Button>
      </div>
    </div>
  );
}