import { useState, useEffect, useCallback } from 'react';
import { api } from '../api';

/**
 * 리비전 상태 관리 훅
 * 리비전 진행 상태, 히스토리, 확정 등 관리
 */
export const useRevisionStatus = (jobNo, fileId) => {
    const [revisionStatus, setRevisionStatus] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const loadRevisionStatus = useCallback(async () => {
        if (!jobNo || !fileId) return;

        try {
            setLoading(true);
            setError(null);

            const response = await api.get(`/revision-status/${jobNo}/${fileId}`);
            
            if (response.data.success) {
                setRevisionStatus(response.data.data);
            }
        } catch (err) {
            console.error('리비전 상태 조회 실패:', err);
            setError(err.message);
        } finally {
            setLoading(false);
        }
    }, [jobNo, fileId]);

    const createComparisonRecord = useCallback(async (previousFileId, comparisonResult) => {
        try {
            const response = await api.post('/revision-status/create-comparison', {
                job_no: jobNo,
                current_file_id: fileId,
                previous_file_id: previousFileId,
                comparison_result: comparisonResult
            });

            if (response.data.success) {
                // 상태 새로고침
                await loadRevisionStatus();
                return response.data.data.comparison_id;
            } else {
                throw new Error(response.data.message || '비교 기록 생성 실패');
            }
        } catch (err) {
            console.error('비교 기록 생성 실패:', err);
            setError(err.message);
            throw err;
        }
    }, [jobNo, fileId, loadRevisionStatus]);

    const applyComparison = useCallback(async (comparisonId) => {
        try {
            setLoading(true);
            
            const response = await api.post(`/revision-status/apply-comparison/${comparisonId}`);

            if (response.data.success) {
                // 상태 새로고침
                await loadRevisionStatus();
                return response.data.data;
            } else {
                throw new Error(response.data.message || '비교 결과 적용 실패');
            }
        } catch (err) {
            console.error('비교 결과 적용 실패:', err);
            setError(err.message);
            throw err;
        } finally {
            setLoading(false);
        }
    }, [loadRevisionStatus]);

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

    return {
        revisionStatus,
        loading,
        error,
        loadRevisionStatus,
        createComparisonRecord,
        applyComparison,
        setError
    };
};

/**
 * 리비전 히스토리 훅
 */
export const useRevisionHistory = (jobNo) => {
    const [history, setHistory] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const loadHistory = useCallback(async () => {
        if (!jobNo) return;

        try {
            setLoading(true);
            setError(null);

            const response = await api.get(`/revision-status/history/${jobNo}`);
            
            if (response.data.success) {
                setHistory(response.data.data || []);
            }
        } catch (err) {
            console.error('리비전 히스토리 조회 실패:', err);
            setError(err.message);
        } finally {
            setLoading(false);
        }
    }, [jobNo]);

    const getRevisionByFileId = useCallback((fileId) => {
        return history.find(revision => revision.file_id === fileId);
    }, [history]);

    const getLatestRevision = useCallback(() => {
        return history.find(revision => revision.is_latest);
    }, [history]);

    const getPreviousRevision = useCallback((currentFileId) => {
        const currentIndex = history.findIndex(revision => revision.file_id === currentFileId);
        return currentIndex > -1 && currentIndex < history.length - 1 
            ? history[currentIndex + 1] 
            : null;
    }, [history]);

    const getNextRevision = useCallback((currentFileId) => {
        const currentIndex = history.findIndex(revision => revision.file_id === currentFileId);
        return currentIndex > 0 
            ? history[currentIndex - 1] 
            : null;
    }, [history]);

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

    return {
        history,
        loading,
        error,
        loadHistory,
        getRevisionByFileId,
        getLatestRevision,
        getPreviousRevision,
        getNextRevision,
        setError
    };
};

/**
 * 대기 중인 리비전 관리 훅
 */
export const usePendingRevisions = (jobNo = null) => {
    const [pendingRevisions, setPendingRevisions] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const loadPendingRevisions = useCallback(async () => {
        try {
            setLoading(true);
            setError(null);

            const url = jobNo 
                ? `/revision-status/pending?job_no=${jobNo}`
                : '/revision-status/pending';

            const response = await api.get(url);
            
            if (response.data.success) {
                setPendingRevisions(response.data.data || []);
            }
        } catch (err) {
            console.error('대기 중인 리비전 조회 실패:', err);
            setError(err.message);
        } finally {
            setLoading(false);
        }
    }, [jobNo]);

    const approvePendingRevision = useCallback(async (comparisonId) => {
        try {
            const response = await api.post(`/revision-status/apply-comparison/${comparisonId}`);

            if (response.data.success) {
                // 대기 목록 새로고침
                await loadPendingRevisions();
                return response.data.data;
            } else {
                throw new Error(response.data.message || '리비전 승인 실패');
            }
        } catch (err) {
            console.error('리비전 승인 실패:', err);
            setError(err.message);
            throw err;
        }
    }, [loadPendingRevisions]);

    const rejectPendingRevision = useCallback(async (comparisonId, reason = '') => {
        try {
            const response = await api.post(`/revision-status/reject-comparison/${comparisonId}`, {
                reason
            });

            if (response.data.success) {
                // 대기 목록 새로고침
                await loadPendingRevisions();
                return response.data.data;
            } else {
                throw new Error(response.data.message || '리비전 거부 실패');
            }
        } catch (err) {
            console.error('리비전 거부 실패:', err);
            setError(err.message);
            throw err;
        }
    }, [loadPendingRevisions]);

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

    return {
        pendingRevisions,
        loading,
        error,
        loadPendingRevisions,
        approvePendingRevision,
        rejectPendingRevision,
        setError
    };
};

/**
 * 리비전 업로드 훅
 */
export const useRevisionUpload = (jobNo, currentFileId) => {
    const [uploading, setUploading] = useState(false);
    const [uploadProgress, setUploadProgress] = useState(0);
    const [error, setError] = useState(null);

    const uploadNewRevision = useCallback(async (file, revisionInfo = {}) => {
        if (!file || !jobNo || !currentFileId) {
            throw new Error('필수 정보가 누락되었습니다.');
        }

        try {
            setUploading(true);
            setUploadProgress(0);
            setError(null);

            const formData = new FormData();
            formData.append('file', file);
            formData.append('job_no', jobNo);
            formData.append('parent_file_id', currentFileId);
            
            // 리비전 정보 추가
            Object.entries(revisionInfo).forEach(([key, value]) => {
                formData.append(key, value);
            });

            const response = await api.post('/files/upload-revision', formData, {
                headers: {
                    'Content-Type': 'multipart/form-data'
                },
                onUploadProgress: (progressEvent) => {
                    const progress = Math.round(
                        (progressEvent.loaded * 100) / progressEvent.total
                    );
                    setUploadProgress(progress);
                }
            });

            if (response.data.success) {
                setUploadProgress(100);
                return response.data.data;
            } else {
                throw new Error(response.data.message || '리비전 업로드 실패');
            }
        } catch (err) {
            console.error('리비전 업로드 실패:', err);
            setError(err.message);
            throw err;
        } finally {
            setUploading(false);
        }
    }, [jobNo, currentFileId]);

    const validateRevisionFile = useCallback((file) => {
        const errors = [];

        // 파일 크기 검증 (100MB 제한)
        if (file.size > 100 * 1024 * 1024) {
            errors.push('파일 크기는 100MB를 초과할 수 없습니다.');
        }

        // 파일 형식 검증
        const allowedTypes = [
            'application/vnd.ms-excel',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'text/csv'
        ];
        
        if (!allowedTypes.includes(file.type)) {
            errors.push('Excel 파일(.xlsx, .xls) 또는 CSV 파일만 업로드 가능합니다.');
        }

        return {
            isValid: errors.length === 0,
            errors
        };
    }, []);

    const resetUpload = useCallback(() => {
        setUploading(false);
        setUploadProgress(0);
        setError(null);
    }, []);

    return {
        uploading,
        uploadProgress,
        error,
        uploadNewRevision,
        validateRevisionFile,
        resetUpload,
        setError
    };
};

/**
 * 리비전 네비게이션 훅
 */
export const useRevisionNavigation = (jobNo, currentFileId) => {
    const { history } = useRevisionHistory(jobNo);
    
    const getCurrentRevisionIndex = useCallback(() => {
        return history.findIndex(revision => revision.file_id === currentFileId);
    }, [history, currentFileId]);

    const canNavigateToPrevious = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return currentIndex > -1 && currentIndex < history.length - 1;
    }, [getCurrentRevisionIndex, history.length]);

    const canNavigateToNext = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return currentIndex > 0;
    }, [getCurrentRevisionIndex]);

    const getPreviousRevision = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return canNavigateToPrevious() ? history[currentIndex + 1] : null;
    }, [getCurrentRevisionIndex, canNavigateToPrevious, history]);

    const getNextRevision = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return canNavigateToNext() ? history[currentIndex - 1] : null;
    }, [getCurrentRevisionIndex, canNavigateToNext, history]);

    const isLatestRevision = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return currentIndex === 0;
    }, [getCurrentRevisionIndex]);

    const isFirstRevision = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return currentIndex === history.length - 1;
    }, [getCurrentRevisionIndex, history.length]);

    const getRevisionPosition = useCallback(() => {
        const currentIndex = getCurrentRevisionIndex();
        return {
            current: currentIndex + 1,
            total: history.length,
            isLatest: isLatestRevision(),
            isFirst: isFirstRevision()
        };
    }, [getCurrentRevisionIndex, history.length, isLatestRevision, isFirstRevision]);

    return {
        canNavigateToPrevious,
        canNavigateToNext,
        getPreviousRevision,
        getNextRevision,
        isLatestRevision,
        isFirstRevision,
        getRevisionPosition
    };
};
