import { useState, useCallback, useEffect, useRef } from 'react'
import { Button, Dialog, Input, Notification, toast } from '@/components/ui'
import Container from '@/components/shared/Container'
import AdaptableCard from '@/components/shared/AdaptableCard'
import { getDataSources } from '@/services/data-source.service'
import type { DataSourceDto } from '@/proxy/data-source'
import type {
  SqlFunctionDto,
  SqlQueryDto,
  SqlStoredProcedureDto,
  SqlViewDto,
  SqlQueryExecutionResultDto,
} from '@/proxy/sql-query-manager/models'
import { SqlObjectType } from '@/proxy/sql-query-manager/models'
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
import { FaDatabase, FaPlay, FaSave, FaSyncAlt, FaCloudUploadAlt, FaCode } from 'react-icons/fa'
import { FaCheckCircle } from 'react-icons/fa'
import { useLocalization } from '@/utils/hooks/useLocalization'
import SqlObjectExplorer from './components/SqlObjectExplorer'
import SqlEditor, { SqlEditorRef } from './components/SqlEditor'
import SqlResultsGrid from './components/SqlResultsGrid'
import SqlObjectProperties from './components/SqlObjectProperties'
import TemplateDialog from './components/TemplateDialog'
import { Splitter } from '@/components/codeLayout/Splitter'
import { Helmet } from 'react-helmet'
import { useStoreState } from '@/store/store'
import { APP_NAME } from '@/constants/app.constant'

export type SqlObject = SqlFunctionDto | SqlQueryDto | SqlStoredProcedureDto | SqlViewDto

interface SqlManagerState {
  dataSources: DataSourceDto[]
  selectedDataSource: string | null
  selectedObject: SqlObject | null
  selectedObjectType: SqlObjectType | null
  editorContent: string
  isExecuting: boolean
  executionResult: SqlQueryExecutionResultDto | null
  showProperties: boolean
  isDirty: boolean
  tableColumns: any | null
  isSaved: boolean
  refreshTrigger: number
}

const SqlQueryManager = () => {
  const { translate } = useLocalization()
  const editorRef = useRef<SqlEditorRef>(null)
  const tenantName = useStoreState((state) => state.locale.currentTenantName)

  const [state, setState] = useState<SqlManagerState>({
    dataSources: [],
    selectedDataSource: tenantName ?? null,
    selectedObject: null,
    selectedObjectType: null,
    editorContent: '',
    isExecuting: false,
    refreshTrigger: 0,
    executionResult: null,
    showProperties: false,
    isDirty: false,
    tableColumns: null,
    isSaved: false,
  })

  const [showSaveDialog, setShowSaveDialog] = useState(false)
  const [saveDialogData, setSaveDialogData] = useState({
    name: '',
    description: '',
    detectedType: '',
    detectedName: '',
    isExistingObject: false,
  })
  const [showTemplateDialog, setShowTemplateDialog] = useState(false)
  const [showTemplateConfirmDialog, setShowTemplateConfirmDialog] = useState(false)
  const [pendingTemplate, setPendingTemplate] = useState<{ content: string; type: string } | null>(
    null,
  )

  useEffect(() => {
    loadDataSources()
  }, [])

  const loadDataSources = async () => {
    try {
      const response = await getDataSources()
      const items = response.data.items || []
      if (items.length > 0) {
        setState((prev) => ({
          ...prev,
          dataSources: items,
          selectedDataSource: items[0].code ?? null,
        }))
      }
    } catch (error) {
      toast.push(
        <Notification type="danger" title={translate('::App.Platform.Error')}>
          {translate('::App.Platform.FailedtoloadDatasources')}
        </Notification>,
        { placement: 'top-center' },
      )
    }
  }

  const handleDataSourceChange = useCallback((dataSource: DataSourceDto) => {
    setState((prev) => ({
      ...prev,
      selectedDataSource: dataSource.code ?? null,
      selectedObject: null,
      editorContent: '',
      executionResult: null,
      isDirty: false,
    }))
  }, [])

  const handleObjectSelect = useCallback(
    async (object: SqlObject | null, objectType: SqlObjectType | null) => {
      if (state.isDirty) {
        if (!confirm(translate('::App.Platform.UnsavedChangesConfirmation'))) {
          return
        }
      }

      let content = ''
      if (object) {
        if (objectType === 1) {
          // Query
          content = (object as SqlQueryDto).queryText || ''
        } else if (objectType === 2) {
          // Stored Procedure
          const sp = object as SqlStoredProcedureDto
          if (sp.isCustom) {
            content = sp.procedureBody || ''
          } else {
            // Native SP - fetch definition from SQL Server
            try {
              const result = await sqlObjectManagerService.getNativeObjectDefinition(
                state.selectedDataSource || '',
                sp.schemaName,
                sp.procedureName
              )
              content = result.data || ''
            } catch (error) {
              toast.push(
                <Notification type="danger" title={translate('::App.Platform.Error')}>
                  {translate('::App.Platform.FailedToLoadDefinition')}
                </Notification>,
                { placement: 'top-center' },
              )
            }
          }
        } else if (objectType === 3) {
          // View
          const view = object as SqlViewDto
          if (view.isCustom) {
            content = view.viewDefinition || ''
          } else {
            // Native View - fetch definition from SQL Server
            try {
              const result = await sqlObjectManagerService.getNativeObjectDefinition(
                state.selectedDataSource || '',
                view.schemaName,
                view.viewName
              )
              content = result.data || ''
            } catch (error) {
              toast.push(
                <Notification type="danger" title={translate('::App.Platform.Error')}>
                  {translate('::App.Platform.FailedToLoadDefinition')}
                </Notification>,
                { placement: 'top-center' },
              )
            }
          }
        } else if (objectType === 4) {
          // Function
          const func = object as SqlFunctionDto
          if (func.isCustom) {
            content = func.functionBody || ''
          } else {
            // Native Function - fetch definition from SQL Server
            try {
              const result = await sqlObjectManagerService.getNativeObjectDefinition(
                state.selectedDataSource || '',
                func.schemaName,
                func.functionName
              )
              content = result.data || ''
            } catch (error) {
              toast.push(
                <Notification type="danger" title={translate('::App.Platform.Error')}>
                  {translate('::App.Platform.FailedToLoadDefinition')}
                </Notification>,
                { placement: 'top-center' },
              )
            }
          }
        }
      }

      setState((prev) => ({
        ...prev,
        selectedObject: object,
        selectedObjectType: objectType,
        editorContent: content,
        executionResult: null,
        tableColumns: null,
        isDirty: false,
        isSaved: false,
      }))
    },
    [state.isDirty, state.selectedDataSource, translate],
  )

  const handleEditorChange = useCallback((value: string | undefined) => {
    setState((prev) => ({
      ...prev,
      editorContent: value || '',
      isDirty: true,
      isSaved: false,
    }))
  }, [])

  const getTemplateContent = (templateType: string): string => {
    const templates: Record<string, string> = {
      select: `-- Basic SELECT query
SELECT 
    Column1,
    Column2,
    Column3
FROM 
    TableName
WHERE 
    -- Add your conditions
    Column1 = 'value'
    AND IsActive = 1
ORDER BY 
    Column1 ASC;`,

      insert: `-- Basic INSERT query
INSERT INTO TableName (Column1, Column2, Column3)
VALUES 
    ('Value1', 'Value2', 'Value3');`,

      update: `-- Basic UPDATE query
UPDATE TableName
SET 
    Column1 = 'NewValue1',
    Column2 = 'NewValue2'
WHERE 
    -- Add your conditions
    Id = 1;`,

      delete: `-- Basic DELETE query
DELETE FROM TableName
WHERE 
    -- Add your conditions
    Id = 1;`,

      'create-procedure': `-- Create Stored Procedure
CREATE PROCEDURE [dbo].[ProcedureName]
    @Parameter1 INT,
    @Parameter2 NVARCHAR(100)
AS
BEGIN
    SET NOCOUNT ON;
    
    -- Add your logic here
    SELECT 
        Column1,
        Column2
    FROM 
        TableName
    WHERE 
        Column1 = @Parameter1
        AND Column2 = @Parameter2;
END
GO`,

      'create-view': `-- Create View
CREATE VIEW [dbo].[ViewName]
AS
SELECT 
    t1.Column1,
    t1.Column2,
    t2.Column3
FROM 
    TableName1 t1
    INNER JOIN TableName2 t2 ON t1.Id = t2.TableName1Id
WHERE 
    t1.IsActive = 1;
GO`,

      'create-scalar-function': `-- Create Scalar Function
CREATE FUNCTION [dbo].[ScalarFunctionName]
(
    @Parameter1 INT,
    @Parameter2 NVARCHAR(100)
)
RETURNS NVARCHAR(200)
AS
BEGIN
    DECLARE @Result NVARCHAR(200);
    
    -- Add your logic here
    SELECT @Result = Column1 + ' ' + @Parameter2
    FROM TableName
    WHERE Id = @Parameter1;
    
    RETURN @Result;
END
GO`,

      'create-table-function': `-- Create Table-Valued Function
CREATE FUNCTION [dbo].[TableFunctionName]
(
    @Parameter1 INT,
    @Parameter2 NVARCHAR(100)
)
RETURNS TABLE
AS
RETURN
(
    SELECT 
        t.Column1,
        t.Column2,
        t.Column3,
        t.Column4
    FROM 
        TableName t
    WHERE 
        t.Id = @Parameter1
        AND t.Column2 LIKE '%' + @Parameter2 + '%'
        AND t.IsActive = 1
)
GO`,
    }

    return templates[templateType] || templates['select']
  }

  // SQL analiz fonksiyonu - SQL metnini analiz edip nesne türünü ve adını tespit eder
  const detectSqlObject = (sql: string): { type: string; name: string } => {
    const upperSql = sql.trim().toUpperCase()

    // VIEW tespiti
    if (upperSql.includes('CREATE VIEW') || upperSql.includes('ALTER VIEW')) {
      // Son kelimeyi al (schema varsa sonraki kelime, yoksa ilk kelime)
      const viewMatch = sql.match(
        /(?:CREATE|ALTER)\s+VIEW\s+(?:[\[\]]*\w+[\[\]]*\.)?\s*[\[]?(\w+)[\]]?/i,
      )
      return {
        type: 'View',
        name: viewMatch ? viewMatch[1] : '',
      }
    }

    // STORED PROCEDURE tespiti
    if (
      upperSql.includes('CREATE PROCEDURE') ||
      upperSql.includes('CREATE PROC') ||
      upperSql.includes('ALTER PROCEDURE') ||
      upperSql.includes('ALTER PROC')
    ) {
      const procMatch = sql.match(
        /(?:CREATE|ALTER)\s+(?:PROCEDURE|PROC)\s+(?:[\[\]]*\w+[\[\]]*\.)?\s*[\[]?(\w+)[\]]?/i,
      )
      return {
        type: 'StoredProcedure',
        name: procMatch ? procMatch[1] : '',
      }
    }

    // FUNCTION tespiti
    if (upperSql.includes('CREATE FUNCTION') || upperSql.includes('ALTER FUNCTION')) {
      const funcMatch = sql.match(
        /(?:CREATE|ALTER)\s+FUNCTION\s+(?:[\[\]]*\w+[\[\]]*\.)?\s*[\[]?(\w+)[\]]?/i,
      )
      return {
        type: 'Function',
        name: funcMatch ? funcMatch[1] : '',
      }
    }

    // Default: Query
    return {
      type: 'Query',
      name: '',
    }
  }

  const applyTemplate = useCallback(
    (templateContent: string) => {
      setState((prev) => ({
        ...prev,
        editorContent: templateContent,
        selectedObject: null,
        selectedObjectType: null,
        executionResult: null,
        isDirty: false,
      }))
    },
    [],
  )

  const handleUseTemplateFromDialog = useCallback(
    (templateContent: string, templateType: string) => {
      // Check if editor has content
      const hasUserContent = state.editorContent?.trim() && state.isDirty

      if (hasUserContent) {
        // Ask for confirmation
        setPendingTemplate({ content: templateContent, type: templateType })
        setShowTemplateConfirmDialog(true)
      } else {
        // Apply template directly
        applyTemplate(templateContent)
      }
    },
    [state.editorContent, state.isDirty, applyTemplate],
  )

  const handleTemplateSelect = useCallback(
    (template: string, templateType: string) => {
      // If template is already provided (e.g., from table click), use it
      const templateContent = template || getTemplateContent(templateType)

      // Check if editor has content and it's not from a previous template
      const hasUserContent = state.editorContent?.trim() && state.isDirty

      if (hasUserContent) {
        // Ask for confirmation
        setPendingTemplate({ content: templateContent, type: templateType })
        setShowTemplateConfirmDialog(true)
      } else {
        // Apply template directly
        applyTemplate(templateContent)
      }
    },
    [translate, state.editorContent, state.isDirty, applyTemplate],
  )

  const handleConfirmTemplateReplace = useCallback(() => {
    if (pendingTemplate) {
      applyTemplate(pendingTemplate.content)
    }
    setShowTemplateConfirmDialog(false)
    setPendingTemplate(null)
  }, [pendingTemplate, applyTemplate])

  const handleCancelTemplateReplace = useCallback(() => {
    setShowTemplateConfirmDialog(false)
    setPendingTemplate(null)
  }, [])

  const handleExecute = async () => {
    if (!state.selectedDataSource) {
      toast.push(
        <Notification type="warning" title={translate('::App.Platform.Warning')}>
          {translate('::App.Platform.PleaseSelectDataSource')}
        </Notification>,
        { placement: 'top-center' },
      )
      return
    }

    // Seçili text varsa onu, yoksa tüm editor içeriğini kullan
    const selectedText = editorRef.current?.getSelectedText() || ''
    const queryToExecute = selectedText.trim() || state.editorContent?.trim() || ''

    if (!queryToExecute) {
      toast.push(
        <Notification type="warning" title={translate('::App.Platform.Warning')}>
          {translate('::App.Platform.PleaseEnterQuery')}
        </Notification>,
        { placement: 'top-center' },
      )
      return
    }

    // Seçili metni koru
    const savedSelection = editorRef.current?.preserveSelection()

    setState((prev) => ({ ...prev, isExecuting: true, executionResult: null, tableColumns: null }))

    try {
      const result = await sqlObjectManagerService.executeQuery({
        queryText: queryToExecute,
        dataSourceCode: state.selectedDataSource || '',
      })

      setState((prev) => ({
        ...prev,
        executionResult: result.data,
        isExecuting: false,
        tableColumns: null,
      }))

      // Seçili metni geri yükle
      setTimeout(() => {
        if (savedSelection) {
          editorRef.current?.restoreSelection(savedSelection)
        }
      }, 100)
    } catch (error: any) {
      setState((prev) => ({ ...prev, isExecuting: false }))

      // Hata durumunda da seçili metni geri yükle
      setTimeout(() => {
        if (savedSelection) {
          editorRef.current?.restoreSelection(savedSelection)
        }
      }, 100)

      toast.push(
        <Notification type="danger" title={translate('::App.Platform.Error')}>
          {error.response?.data?.error?.message || translate('::App.Platform.FailedToExecuteQuery')}
        </Notification>,
        { placement: 'top-center' },
      )
    }
  }

  const handleSave = async () => {
    if (!state.selectedDataSource) {
      toast.push(
        <Notification type="warning" title={translate('::App.Platform.Warning')}>
          {translate('::App.Platform.PleaseSelectDataSource')}
        </Notification>,
        { placement: 'top-center' },
      )
      return
    }

    if (!state.editorContent?.trim()) {
      toast.push(
        <Notification type="warning" title={translate('::App.Platform.Warning')}>
          {translate('::App.Platform.PleaseEnterContentToSave')}
        </Notification>,
        { placement: 'top-center' },
      )
      return
    }

    if (state.selectedObject && state.selectedObjectType) {
      // Update existing object - open dialog with existing data
      const typeMap: Record<SqlObjectType, string> = {
        [SqlObjectType.Query]: 'Query',
        [SqlObjectType.View]: 'View',
        [SqlObjectType.StoredProcedure]: 'StoredProcedure',
        [SqlObjectType.Function]: 'Function',
      }

      // Get name based on object type
      let objectName = ''
      if ('viewName' in state.selectedObject) {
        objectName = state.selectedObject.viewName || state.selectedObject.displayName || ''
      } else if ('procedureName' in state.selectedObject) {
        objectName = state.selectedObject.procedureName || state.selectedObject.displayName || ''
      } else if ('functionName' in state.selectedObject) {
        objectName = state.selectedObject.functionName || state.selectedObject.displayName || ''
      } else if ('name' in state.selectedObject) {
        objectName = state.selectedObject.name || ''
      }

      setSaveDialogData({
        name: objectName,
        description: state.selectedObject.description || '',
        detectedType: typeMap[state.selectedObjectType] || '',
        detectedName: objectName,
        isExistingObject: true,
      })
      setShowSaveDialog(true)
    } else {
      // New object - analyze SQL and show dialog with detection
      const detection = detectSqlObject(state.editorContent)
      setSaveDialogData({
        name: detection.name,
        description: '',
        detectedType: detection.type,
        detectedName: detection.name,
        isExistingObject: false,
      })
      setShowSaveDialog(true)
    }
  }

  const handleCreateNewQuery = async () => {
    if (!state.selectedDataSource || !saveDialogData.name) return

    try {
      // Smart save ile kaydet
      const result = await sqlObjectManagerService.smartSave({
        sqlText: state.editorContent,
        dataSourceCode: state.selectedDataSource || '',
        name: saveDialogData.name,
        description: saveDialogData.description,
      })

      // Kaydedilen objeyi state'e set et
      const savedObject: any = {
        id: result.data.objectId,
        displayName: saveDialogData.name,
        description: saveDialogData.description,
        isDeployed: result.data.deployed,
      }

      // ObjectType'a göre ekstra alanlar ekle
      let objectType: SqlObjectType | null = null
      if (result.data.objectType === 'View') {
        objectType = SqlObjectType.View
        savedObject.viewName = saveDialogData.name
        savedObject.viewDefinition = state.editorContent
      } else if (result.data.objectType === 'StoredProcedure') {
        objectType = SqlObjectType.StoredProcedure
        savedObject.procedureName = saveDialogData.name
        savedObject.procedureBody = state.editorContent
      } else if (result.data.objectType === 'Function') {
        objectType = SqlObjectType.Function
        savedObject.functionName = saveDialogData.name
        savedObject.functionBody = state.editorContent
      } else if (result.data.objectType === 'Query') {
        objectType = SqlObjectType.Query
        savedObject.queryText = state.editorContent
      }

      setState((prev) => ({
        ...prev,
        isDirty: false,
        isSaved: true,
        selectedObject: savedObject,
        selectedObjectType: objectType,
        refreshTrigger: prev.refreshTrigger + 1,
      }))
      setShowSaveDialog(false)

      toast.push(
        <Notification type="success" title={translate('::App.Platform.Success')}>
          {result.data.message || translate('::App.Platform.SavedSuccessfully')}
        </Notification>,
        { placement: 'top-center' },
      )
    } catch (error: any) {
      toast.push(
        <Notification type="danger" title={translate('::App.Platform.Error')}>
          {error.response?.data?.error?.message || translate('::App.Platform.FailedToSaveQuery')}
        </Notification>,
        { placement: 'top-center' },
      )
    }
  }

  const handleDeploy = async () => {
    if (!state.selectedObject || !state.selectedObjectType) {
      toast.push(
        <Notification type="warning" title={translate('::App.Platform.Warning')}>
          {translate('::App.Platform.PleaseSelectAnObjectToDeploy')}
        </Notification>,
        { placement: 'top-center' },
      )
      return
    }
    if (!state.selectedObject.id) return

    try {
      const objectId = state.selectedObject.id
      let result: any

      switch (state.selectedObjectType) {
        case SqlObjectType.StoredProcedure:
          result = await sqlObjectManagerService.deployStoredProcedure({
            id: objectId,
            dropIfExists: true,
          })
          break
        case SqlObjectType.View:
          result = await sqlObjectManagerService.deployView({ id: objectId, dropIfExists: true })
          break
        case SqlObjectType.Function:
          result = await sqlObjectManagerService.deployFunction({
            id: objectId,
            dropIfExists: true,
          })
          break
        default:
          toast.push(
            <Notification type="warning" title={translate('::App.Platform.Warning')}>
              {translate('::App.Platform.ThisObjectTypeCannotBeDeployed')}
            </Notification>,
            { placement: 'top-center' },
          )
          return
      }

      // Update selectedObject's isDeployed status
      setState((prev) => ({
        ...prev,
        selectedObject: prev.selectedObject ? { ...prev.selectedObject, isDeployed: true } : null,
        refreshTrigger: prev.refreshTrigger + 1,
      }))

      toast.push(
        <Notification type="success" title={translate('::App.Platform.Success')}>
          {translate('::App.Platform.ObjectDeployedSuccessfully')}
        </Notification>,
        { placement: 'top-center' },
      )
    } catch (error: any) {
      toast.push(
        <Notification type="danger" title={translate('::App.Platform.Error')}>
          {error.response?.data?.error?.message || translate('::App.Platform.FailedToDeployObject')}
        </Notification>,
        { placement: 'top-center' },
      )
    }
  }

  const handleShowTableColumns = async (schemaName: string, tableName: string) => {
    if (!state.selectedDataSource) return

    try {
      const response = await sqlObjectManagerService.getTableColumns(
        state.selectedDataSource || '',
        schemaName,
        tableName,
      )

      // Transform API response to match display format
      const transformedData = response.data.map((col: any) => ({
        ColumnName: col.columnName,
        DataType: col.dataType,
        MaxLength: col.maxLength || '-',
        IsNullable: col.isNullable,
        IsPrimaryKey: col.isPrimaryKey || false,
      }))

      // Create a result object that looks like execution result for display
      const columnsResult = {
        success: true,
        message: `Columns for ${schemaName}.${tableName}`,
        data: transformedData,
        rowsAffected: transformedData.length,
        executionTimeMs: 0,
        metadata: {
          columns: [
            { name: 'ColumnName', dataType: 'string' },
            { name: 'DataType', dataType: 'string' },
            { name: 'MaxLength', dataType: 'string' },
            { name: 'IsNullable', dataType: 'boolean' },
            { name: 'IsPrimaryKey', dataType: 'boolean' },
          ],
        },
      }

      setState((prev) => ({
        ...prev,
        tableColumns: columnsResult,
        executionResult: null, // Clear query results when showing columns
      }))
    } catch (error: any) {
      toast.push(
        <Notification type="danger" title={translate('::App.Platform.Error')}>
          {error.response?.data?.error?.message || translate('::App.Platform.FailedToLoadColumns')}
        </Notification>,
        { placement: 'top-center' },
      )
    }
  }

  return (
    <Container className="h-full overflow-hidden">
      <Helmet
        titleTemplate={`%s | ${APP_NAME}`}
        title={translate('::' + 'App.SqlQueryManager')}
        defaultTitle={APP_NAME}
      ></Helmet>

      <div className="flex flex-col h-full p-1">
        {/* Toolbar */}
        <div className="flex-shrink-0 shadow-sm mb-4">
          <div className="flex items-center justify-between px-1 py-1">
            <div className="flex items-center gap-3">
              <FaDatabase className="text-lg text-blue-500" />
              <span className="text-sm font-medium text-gray-600 dark:text-gray-400">
                {translate('::App.Platform.DataSource')}:
              </span>
              <select
                className="border border-gray-300 rounded px-1 py-1"
                disabled={state.selectedDataSource?.length === 0}
                value={state.selectedDataSource || ''}
                onChange={(e) => {
                  const ds = state.dataSources.find((d) => d.code === e.target.value)
                  if (ds) handleDataSourceChange(ds)
                }}
              >
                {state.dataSources.map((ds) => (
                  <option key={ds.code} value={ds.code}>
                    {ds.code}
                  </option>
                ))}
              </select>
            </div>

            <div className="flex items-center gap-3">
              <Button
                size="sm"
                variant="solid"
                color="orange-500"
                icon={<FaCode />}
                onClick={() => setShowTemplateDialog(true)}
                className="shadow-sm"
              >
                {translate('::App.Platform.Templates')}
              </Button>
              <Button
                size="sm"
                variant="solid"
                color="blue-600"
                icon={<FaPlay />}
                onClick={handleExecute}
                loading={state.isExecuting}
                disabled={!state.selectedDataSource}
                className="shadow-sm"
              >
                {translate('::App.Platform.Execute')}
                <span className="ml-1 text-xs opacity-75">(F5)</span>
              </Button>
              <Button
                size="sm"
                variant="solid"
                icon={<FaSave />}
                onClick={handleSave}
                disabled={
                  !state.selectedDataSource ||
                  !state.editorContent?.trim() ||
                  (state.isSaved && !state.isDirty) ||
                  !state.executionResult?.success
                }
                className="shadow-sm"
              >
                {translate('::App.Platform.Save')}
                <span className="ml-1 text-xs opacity-75">(Ctrl+S)</span>
              </Button>
              <Button
                size="sm"
                variant="solid"
                color="green-600"
                icon={<FaCloudUploadAlt />}
                onClick={handleDeploy}
                disabled={
                  !state.selectedObject ||
                  !state.selectedObjectType ||
                  state.selectedObjectType === SqlObjectType.Query ||
                  (state.selectedObject &&
                    'isDeployed' in state.selectedObject &&
                    state.selectedObject.isDeployed)
                }
                className="shadow-sm"
              >
                {translate('::App.Platform.Deploy')}
              </Button>
            </div>
          </div>
        </div>

        {/* Main Content Area */}
        <div className="flex-1 flex min-h-0">
          {/* Left Panel - Object Explorer */}
          <div className="w-1/3 flex-shrink-0 flex flex-col min-h-0 mr-4">
            <AdaptableCard className="h-full" bodyClass="p-0">
              <div className="h-full flex flex-col">
                <div className="border-b px-4 py-2 bg-gray-50 dark:bg-gray-800 flex-shrink-0">
                  <h6 className="font-semibold text-sm">
                    {translate('::App.Platform.ObjectExplorer')}
                  </h6>
                </div>
                <SqlObjectExplorer
                  dataSource={state.selectedDataSource}
                  onObjectSelect={handleObjectSelect}
                  selectedObject={state.selectedObject}
                  onTemplateSelect={handleTemplateSelect}
                  onShowTableColumns={handleShowTableColumns}
                  refreshTrigger={state.refreshTrigger}
                />
              </div>
            </AdaptableCard>
          </div>

          {/* Center Panel - Editor and Results */}
          <div className="flex-1 flex flex-col min-h-0 mr-4">
            {state.executionResult || state.tableColumns ? (
              <Splitter direction="vertical" initialSize={250} minSize={150} maxSize={1200}>
                <div className="border rounded-lg shadow-sm bg-white dark:bg-gray-800 flex flex-col h-full">
                  <div className="border-b px-4 py-2 bg-gray-50 dark:bg-gray-800 flex-shrink-0">
                    <h6 className="font-semibold text-sm">
                      {translate('::App.Platform.QueryEditor')}
                    </h6>
                  </div>
                  <div className="flex-1 min-h-0 overflow-hidden">
                    <SqlEditor
                      ref={editorRef}
                      value={state.editorContent}
                      onChange={handleEditorChange}
                      onExecute={handleExecute}
                      onSave={handleSave}
                      readOnly={state.isExecuting}
                    />
                  </div>
                </div>
                <div className="border rounded-lg shadow-sm bg-white dark:bg-gray-800 flex flex-col h-full">
                  <div className="border-b px-4 py-2 bg-gray-50 dark:bg-gray-800 flex-shrink-0 flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <FaCheckCircle className="text-green-500" />
                      <span className="text-sm text-green-700 dark:text-green-400">
                        {state.executionResult?.message ||
                          state.tableColumns?.message ||
                          translate('::App.Platform.QueryExecutedSuccessfully')}
                      </span>
                    </div>
                    <div className="flex items-center gap-4">
                      <div className="flex items-center gap-4 text-sm text-gray-600 dark:text-gray-400">
                        <span>
                          {translate('::App.Platform.Rows')}:{' '}
                          <strong>
                            {state.executionResult?.rowsAffected ||
                              state.executionResult?.data?.length ||
                              state.tableColumns?.rowsAffected ||
                              0}
                          </strong>
                        </span>
                        {state.executionResult && (
                          <span>
                            {translate('::App.Platform.Time')}:{' '}
                            <strong>{state.executionResult.executionTimeMs}ms</strong>
                          </span>
                        )}
                      </div>
                    </div>
                  </div>
                  <div className="flex-1 overflow-hidden p-2">
                    <SqlResultsGrid result={(state.executionResult || state.tableColumns)!} />
                  </div>
                </div>
              </Splitter>
            ) : (
              <div className="flex-1 border rounded-lg shadow-sm bg-white dark:bg-gray-800 flex flex-col overflow-hidden">
                <div className="border-b px-4 py-2 bg-gray-50 dark:bg-gray-800 flex-shrink-0">
                  <h6 className="font-semibold text-sm">
                    {translate('::App.Platform.QueryEditor')}
                  </h6>
                </div>
                <div className="flex-1 min-h-0">
                  <SqlEditor
                    ref={editorRef}
                    value={state.editorContent}
                    onChange={handleEditorChange}
                    onExecute={handleExecute}
                    onSave={handleSave}
                    readOnly={state.isExecuting}
                  />
                </div>
              </div>
            )}
          </div>

          {/* Right Panel - Properties (Optional) */}
          {state.showProperties && state.selectedObject && (
            <div className="w-80 flex-shrink-0 flex flex-col min-h-0">
              <SqlObjectProperties object={state.selectedObject} type={state.selectedObjectType} />
            </div>
          )}
        </div>
      </div>

      {/* Template Dialog */}
      <TemplateDialog
        isOpen={showTemplateDialog}
        onClose={() => setShowTemplateDialog(false)}
        onUseTemplate={handleUseTemplateFromDialog}
      />

      {/* Template Confirmation Dialog */}
      <Dialog
        isOpen={showTemplateConfirmDialog}
        onClose={handleCancelTemplateReplace}
        onRequestClose={handleCancelTemplateReplace}
      >
        <h5 className="mb-4">{translate('::App.Platform.ConfirmTemplateReplace')}</h5>
        <p className="mb-6 text-gray-600 dark:text-gray-400">
          {translate('::App.Platform.TemplateReplaceWarning')}
        </p>
        <div className="flex justify-end gap-2">
          <Button variant="plain" onClick={handleCancelTemplateReplace}>
            {translate('::Cancel')}
          </Button>
          <Button variant="solid" onClick={handleConfirmTemplateReplace}>
            {translate('::App.Platform.Replace')}
          </Button>
        </div>
      </Dialog>

      {/* Save Dialog */}
      <Dialog
        isOpen={showSaveDialog}
        onClose={() => setShowSaveDialog(false)}
        onRequestClose={() => setShowSaveDialog(false)}
      >
        <h5 className="mb-4">{translate('::App.Platform.SaveQuery')}</h5>
        <div className="space-y-4">
          {/* Detected Object Type */}
          {saveDialogData.detectedType && (
            <div className="p-3 bg-blue-50 dark:bg-blue-900/20 rounded-md border border-blue-200 dark:border-blue-800">
              <div className="flex items-center gap-2">
                <FaCheckCircle className="text-blue-600 dark:text-blue-400 text-xl" />
                <div>
                  <div className="text-sm font-semibold text-blue-900 dark:text-blue-100">
                    {translate('::App.Platform.DetectedObjectType')}
                  </div>
                  <div className="text-sm text-blue-700 dark:text-blue-300">
                    {saveDialogData.detectedType === 'View' && translate('::App.Platform.View')}
                    {saveDialogData.detectedType === 'StoredProcedure' &&
                      translate('::App.Platform.StoredProcedure')}
                    {saveDialogData.detectedType === 'Function' &&
                      translate('::App.Platform.Function')}
                    {saveDialogData.detectedType === 'Query' && translate('::App.Platform.Query')}
                  </div>
                  {saveDialogData.detectedName && (
                    <div className="text-xs text-blue-600 dark:text-blue-400 mt-1">
                      {translate('::App.Platform.DetectedName')}:{' '}
                      <span className="font-mono">{saveDialogData.detectedName}</span>
                    </div>
                  )}
                </div>
              </div>
            </div>
          )}

          <div>
            <label className="block mb-2">
              {translate('::App.Platform.Name')} <span className="text-red-500">*</span>
              {saveDialogData.isExistingObject && (
                <span className="text-xs text-gray-500 ml-2">
                  ({translate('::App.Platform.CannotBeChanged')})
                </span>
              )}
            </label>
            <Input
              autoFocus={!saveDialogData.isExistingObject}
              value={saveDialogData.name}
              onChange={(e) => setSaveDialogData((prev) => ({ ...prev, name: e.target.value }))}
              placeholder={saveDialogData.detectedName || translate('::App.Platform.Name')}
              invalid={!saveDialogData.name.trim()}
              disabled={saveDialogData.isExistingObject}
            />
          </div>
          <div>
            <label className="block mb-2">{translate('::App.Platform.Description')}</label>
            <Input
              value={saveDialogData.description}
              onChange={(e) =>
                setSaveDialogData((prev) => ({ ...prev, description: e.target.value }))
              }
              placeholder={translate('::App.Platform.Description')}
            />
          </div>
          <div className="flex justify-end gap-2">
            <Button variant="plain" onClick={() => setShowSaveDialog(false)}>
              {translate('::Cancel')}
            </Button>
            <Button
              variant="solid"
              onClick={handleCreateNewQuery}
              disabled={!saveDialogData.name.trim()}
            >
              {translate('::App.Platform.Save')}
            </Button>
          </div>
        </div>
      </Dialog>
    </Container>
  )
}

export default SqlQueryManager
