import React, {useEffect, useState} from 'react';
import {Button} from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle
} from '@/components/ui/dialog';
import {ScrollArea} from '@/components/ui/scroll-area';
import MockRouteRequest from '@/components/mock-route/MockRouteRequest';
import MockRouteResponses from '@/components/mock-route/MockRouteResponses';
import {useAPI} from '@/providers/APIProvider';
import {Separator} from '@/components/ui/separator.jsx';

const MockRouteEditDialog = ({open, onOpenChange, item}) => {
  const { createMockRoute, updateMockRoute } = useAPI();
  const [mockRoute, setMockRoute] = useState({
    id: null,
    method: 'POST',
    pathPattern: '',
    name: '',
    description: '',
    requestScript: '',
    responses: [
      {
        statusCode: 200,
        delay: 0,
        encodingCharset: '',
        defaultResponse: 'true',
        conditions: [],
        headers: [],
        body: ''
      }
    ]
  });

  // Initialize form when item changes
  useEffect(() => {
    if (item) {
      setMockRoute(item);
    } else {
      // Reset to default state when creating new
      setMockRoute({
        id: null,
        method: 'POST',
        pathPattern: '',
        name: '',
        description: '',
        requestScript: '',
        responses: [
          {
            statusCode: 200,
            delay: 0,
            encodingCharset: '',
            defaultResponse: 'true',
            conditions: [],
            headers: [],
            body: ''
          }
        ]
      });
    }
  }, [item]);

  const handleChange = (field, value) => {
    setMockRoute((prev) => ({...prev, [field]: value}));
  };

  const handleScriptChange = (value) => {
    setMockRoute((prev) => ({...prev, requestScript: value}));
  };

  const addResponse = () => {
    setMockRoute((prev) => ({
      ...prev,
      responses: [
        ...prev.responses,
        {
          statusCode: 200,
          delay: 0,
          encodingCharset: '',
          defaultResponse: 'false',
          conditions: [],
          headers: [],
          body: ''
        }
      ]
    }));
  };

  const handleOpenChange = (open) => {
    if (!open) {
      setMockRoute({
        id: null,
        method: 'POST',
        pathPattern: '',
        name: '',
        description: '',
        requestScript: '',
        responses: [
          {
            statusCode: 200,
            delay: 0,
            encodingCharset: '',
            defaultResponse: 'true',
            conditions: [],
            headers: [],
            body: ''
          }
        ]
      });
    }
    onOpenChange(open);
  };

  const removeResponse = (index) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      if (newResponses[index].defaultResponse === 'true') {
        alert('기본 응답은 삭제할 수 없습니다.');
        return prev;
      }
      newResponses.splice(index, 1);
      return {...prev, responses: newResponses};
    });
  };

  const updateResponseField = (index, field, value) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      newResponses[index] = {...newResponses[index], [field]: value};
      return {...prev, responses: newResponses};
    });
  };

  const addCondition = (respIndex) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      newResponses[respIndex] = {
        ...newResponses[respIndex],
        conditions: [
          ...newResponses[respIndex].conditions,
          {type: 'query', key: '', value: ''}
        ]
      };
      return {...prev, responses: newResponses};
    });
  };

  const removeCondition = (respIndex, condIndex) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      const newConds = [...newResponses[respIndex].conditions];
      newConds.splice(condIndex, 1);
      newResponses[respIndex] = {
        ...newResponses[respIndex],
        conditions: newConds
      };
      return {...prev, responses: newResponses};
    });
  };

  const updateConditionField = (respIndex, condIndex, field, value) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      const newConds = [...newResponses[respIndex].conditions];
      newConds[condIndex] = {...newConds[condIndex], [field]: value};
      newResponses[respIndex] = {
        ...newResponses[respIndex],
        conditions: newConds
      };
      return {...prev, responses: newResponses};
    });
  };

  const addHeader = (respIndex) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      newResponses[respIndex] = {
        ...newResponses[respIndex],
        headers: [...newResponses[respIndex].headers, {key: '', value: ''}]
      };
      return {...prev, responses: newResponses};
    });
  };

  const removeHeader = (respIndex, hdrIndex) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      const newHeaders = [...newResponses[respIndex].headers];
      newHeaders.splice(hdrIndex, 1);
      newResponses[respIndex] = {
        ...newResponses[respIndex],
        headers: newHeaders
      };
      return {...prev, responses: newResponses};
    });
  };

  const updateHeaderField = (respIndex, hdrIndex, field, value) => {
    setMockRoute((prev) => {
      const newResponses = [...prev.responses];
      const newHeaders = [...newResponses[respIndex].headers];
      newHeaders[hdrIndex] = {...newHeaders[hdrIndex], [field]: value};
      newResponses[respIndex] = {
        ...newResponses[respIndex],
        headers: newHeaders
      };
      return {...prev, responses: newResponses};
    });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      if (mockRoute.id) {
        await updateMockRoute(mockRoute);
      } else {
        await createMockRoute(mockRoute);
      }
      onOpenChange(false);
    } catch (error) {
      console.error('Failed to save mock route:', error);
      alert('Failed to save mock route');
    }
  };

  return (
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="max-w-full h-screen">
          <DialogHeader>
            <DialogTitle>
              {mockRoute.id == null ? 'API 정보 등록' : 'API 정보 수정'}
            </DialogTitle>
            <DialogDescription>
              API 라우트의 정보를 입력하거나 수정할 수 있습니다. 필수 항목을 모두 입력해주세요.
            </DialogDescription>
          </DialogHeader>
          <ScrollArea className="max-h-[100vh] w-full pr-2">
            <MockRouteRequest
                name={mockRoute.name}
                method={mockRoute.method}
                pathPattern={mockRoute.pathPattern}
                requestScript={mockRoute.requestScript}
                onChange={handleChange}
                onScriptChange={handleScriptChange}
            />
            <Separator className="mb-2 mt-2"/>
            <MockRouteResponses
                responses={mockRoute.responses}
                onAddResponse={addResponse}
                onRemoveResponse={removeResponse}
                onAddCondition={addCondition}
                onRemoveCondition={removeCondition}
                onUpdateConditionField={updateConditionField}
                onUpdateResponseField={updateResponseField}
                onAddHeader={addHeader}
                onRemoveHeader={removeHeader}
                onUpdateHeaderField={updateHeaderField}
            />
          </ScrollArea>
          <DialogFooter className="flex justify-end space-x-2">
            <Button variant="secondary" onClick={() => handleOpenChange(false)}>
              닫기
            </Button>
            <Button type="submit" variant="default" onClick={handleSubmit}>
              저장
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
  );
};

export default MockRouteEditDialog;
