import { useEffect, useState, useCallback, useRef } from 'react';
import { 
  Table, 
  Button, 
  Tag, 
  Space, 
  Select, 
  Modal, 
  Form, 
  Input, 
  Upload, 
  message, 
  Progress,
  Typography,
  Tooltip,
  Popconfirm,
  Spin,
  Card,
  Descriptions,
  List,
  Alert
} from 'antd';
import { 
  PlusOutlined, 
  ReloadOutlined, 
  DeleteOutlined, 
  EyeOutlined,
  UploadOutlined,
  CloudServerOutlined,
  ExclamationCircleOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  SyncOutlined,
  ClockCircleOutlined
} from '@ant-design/icons';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import type { UploadFile } from 'antd/es/upload/interface';
import type { ScanTask, AWSCredential, ErrorLog } from '../types';
import { taskService } from '../services/tasks';
import { credentialService } from '../services/credentials';
import { usePagination } from '../hooks/usePagination';
import { formatDateTime } from '../utils';

const { Title, Text } = Typography;
const { Option } = Select;

// AWS Regions list
const AWS_REGIONS = [
  { value: 'us-east-1', label: 'US East (N. Virginia)' },
  { value: 'us-east-2', label: 'US East (Ohio)' },
  { value: 'us-west-1', label: 'US West (N. California)' },
  { value: 'us-west-2', label: 'US West (Oregon)' },
  { value: 'ap-south-1', label: 'Asia Pacific (Mumbai)' },
  { value: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' },
  { value: 'ap-northeast-2', label: 'Asia Pacific (Seoul)' },
  { value: 'ap-northeast-3', label: 'Asia Pacific (Osaka)' },
  { value: 'ap-southeast-1', label: 'Asia Pacific (Singapore)' },
  { value: 'ap-southeast-2', label: 'Asia Pacific (Sydney)' },
  { value: 'ca-central-1', label: 'Canada (Central)' },
  { value: 'eu-central-1', label: 'Europe (Frankfurt)' },
  { value: 'eu-west-1', label: 'Europe (Ireland)' },
  { value: 'eu-west-2', label: 'Europe (London)' },
  { value: 'eu-west-3', label: 'Europe (Paris)' },
  { value: 'eu-north-1', label: 'Europe (Stockholm)' },
  { value: 'sa-east-1', label: 'South America (São Paulo)' },
];

const statusColors: Record<string, string> = {
  pending: 'default',
  running: 'processing',
  completed: 'success',
  failed: 'error',
};

const statusIcons: Record<string, React.ReactNode> = {
  pending: <ClockCircleOutlined />,
  running: <SyncOutlined spin />,
  completed: <CheckCircleOutlined />,
  failed: <CloseCircleOutlined />,
};

export default function Tasks() {
  const [tasks, setTasks] = useState<ScanTask[]>([]);
  const [loading, setLoading] = useState(false);
  const [statusFilter, setStatusFilter] = useState<string | undefined>(undefined);
  const [createModalVisible, setCreateModalVisible] = useState(false);
  const [detailModalVisible, setDetailModalVisible] = useState(false);
  const [selectedTask, setSelectedTask] = useState<ScanTask | null>(null);
  const [credentials, setCredentials] = useState<AWSCredential[]>([]);
  const [credentialsLoading, setCredentialsLoading] = useState(false);
  const [creating, setCreating] = useState(false);
  const [deleting, setDeleting] = useState<number | null>(null);
  const [taskLogs, setTaskLogs] = useState<ErrorLog[]>([]);
  const [logsLoading, setLogsLoading] = useState(false);
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  
  const pagination = usePagination(10);
  const [form] = Form.useForm();
  const refreshIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const detailRefreshIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  // Fetch tasks with specific page/pageSize
  const fetchTasksWithParams = useCallback(async (page: number, pageSize: number, status?: string) => {
    try {
      setLoading(true);
      const response = await taskService.getTasks({
        page,
        pageSize,
        status,
      });
      setTasks(response.data);
      pagination.setTotal(response.pagination.total);
    } catch (error) {
      message.error('Failed to load tasks');
    } finally {
      setLoading(false);
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Wrapper for refresh button and other calls
  const fetchTasks = useCallback(() => {
    fetchTasksWithParams(pagination.page, pagination.pageSize, statusFilter);
  }, [fetchTasksWithParams, pagination.page, pagination.pageSize, statusFilter]);

  // Fetch credentials for create form
  const fetchCredentials = async () => {
    try {
      setCredentialsLoading(true);
      const response = await credentialService.getCredentials({ page: 1, pageSize: 100 });
      setCredentials(response.data.filter(c => c.is_active));
    } catch (error) {
      message.error('Failed to load credentials');
    } finally {
      setCredentialsLoading(false);
    }
  };

  // Fetch task logs
  const fetchTaskLogs = async (taskId: number) => {
    try {
      setLogsLoading(true);
      const response = await taskService.getTaskLogs(taskId, { page: 1, pageSize: 50 });
      setTaskLogs(response.data);
    } catch (error) {
      message.error('Failed to load task logs');
    } finally {
      setLogsLoading(false);
    }
  };

  // Initial load only
  useEffect(() => {
    fetchTasksWithParams(pagination.page, pagination.pageSize, statusFilter);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Auto-refresh for running tasks
  useEffect(() => {
    const hasRunningTasks = tasks.some((t: ScanTask) => t.status === 'running' || t.status === 'pending');
    
    if (hasRunningTasks) {
      refreshIntervalRef.current = setInterval(() => {
        fetchTasks();
      }, 5000); // Refresh every 5 seconds
    }
    
    return () => {
      if (refreshIntervalRef.current) {
        clearInterval(refreshIntervalRef.current);
        refreshIntervalRef.current = null;
      }
    };
  }, [tasks, fetchTasks]);

  // Handle table pagination change
  const handleTableChange = async (paginationConfig: TablePaginationConfig) => {
    const newPage = paginationConfig.current ?? pagination.page;
    // Only use new pageSize if it actually changed (user clicked size changer)
    const newPageSize = paginationConfig.pageSize ?? pagination.pageSize;
    
    pagination.setPage(newPage);
    if (newPageSize !== pagination.pageSize) {
      pagination.setPageSize(newPageSize);
    }
    
    // Directly fetch with new params
    await fetchTasksWithParams(newPage, newPageSize, statusFilter);
  };

  // Handle status filter change
  const handleStatusFilterChange = (value: string | undefined) => {
    setStatusFilter(value);
    pagination.setPage(1);
    fetchTasksWithParams(1, pagination.pageSize, value);
  };

  // Open create modal
  const handleOpenCreateModal = () => {
    fetchCredentials();
    setCreateModalVisible(true);
    setFileList([]);
    form.resetFields();
  };

  // Handle create task
  const handleCreateTask = async (values: Record<string, unknown>) => {
    try {
      setCreating(true);
      
      const formData = new FormData();
      formData.append('name', values.name as string);
      formData.append('credential_ids', JSON.stringify(values.credentialIds));
      formData.append('regions', JSON.stringify(values.regions));
      formData.append('project_metadata', JSON.stringify({
        clientName: values.clientName,
        projectName: values.projectName,
        bdManager: values.bdManager || '',
        bdManagerEmail: values.bdManagerEmail || '',
        solutionsArchitect: values.solutionsArchitect || '',
        solutionsArchitectEmail: values.solutionsArchitectEmail || '',
        cloudEngineer: values.cloudEngineer || '',
        cloudEngineerEmail: values.cloudEngineerEmail || '',
      }));
      
      // Add network diagram if uploaded
      if (fileList.length > 0 && fileList[0].originFileObj) {
        formData.append('network_diagram', fileList[0].originFileObj);
      }
      
      await taskService.createTaskWithFormData(formData);
      message.success('Task created successfully');
      setCreateModalVisible(false);
      form.resetFields();
      setFileList([]);
      fetchTasks();
    } catch (error: unknown) {
      const err = error as { response?: { data?: { error?: { message?: string } } } };
      message.error(err.response?.data?.error?.message || 'Failed to create task');
    } finally {
      setCreating(false);
    }
  };

  // Refresh task detail
  const refreshTaskDetail = useCallback(async (taskId: number) => {
    try {
      const detail = await taskService.getTaskDetail(taskId);
      setSelectedTask(detail);
      // Also refresh logs
      const logsResponse = await taskService.getTaskLogs(taskId, { page: 1, pageSize: 50 });
      setTaskLogs(logsResponse.data);
    } catch (error) {
      // Silently fail for auto-refresh
      console.error('Failed to refresh task details:', error);
    }
  }, []);

  // Handle view task detail
  const handleViewTask = async (task: ScanTask) => {
    try {
      const detail = await taskService.getTaskDetail(task.id);
      setSelectedTask(detail);
      setDetailModalVisible(true);
      fetchTaskLogs(task.id);
    } catch (error) {
      message.error('Failed to load task details');
    }
  };

  // Auto-refresh for task detail modal when task is running/pending
  useEffect(() => {
    if (detailModalVisible && selectedTask && (selectedTask.status === 'running' || selectedTask.status === 'pending')) {
      detailRefreshIntervalRef.current = setInterval(() => {
        refreshTaskDetail(selectedTask.id);
      }, 3000); // Refresh every 3 seconds
    }
    
    return () => {
      if (detailRefreshIntervalRef.current) {
        clearInterval(detailRefreshIntervalRef.current);
        detailRefreshIntervalRef.current = null;
      }
    };
  }, [detailModalVisible, selectedTask?.id, selectedTask?.status, refreshTaskDetail]);

  // Handle delete task
  const handleDeleteTask = async (taskId: number) => {
    try {
      setDeleting(taskId);
      await taskService.deleteTask(taskId);
      message.success('Task deleted successfully');
      fetchTasks();
    } catch (error: unknown) {
      const err = error as { response?: { data?: { error?: { message?: string } } } };
      message.error(err.response?.data?.error?.message || 'Failed to delete task');
    } finally {
      setDeleting(null);
    }
  };

  // Table columns
  const columns: ColumnsType<ScanTask> = [
    { 
      title: 'ID', 
      dataIndex: 'id', 
      key: 'id', 
      width: 80 
    },
    { 
      title: 'Name', 
      dataIndex: 'name', 
      key: 'name',
      ellipsis: true,
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 120,
      render: (status: string) => (
        <Tag color={statusColors[status]} icon={statusIcons[status]}>
          {status.toUpperCase()}
        </Tag>
      ),
    },
    { 
      title: 'Progress', 
      dataIndex: 'progress', 
      key: 'progress',
      width: 150,
      render: (progress: number, record: ScanTask) => (
        <Progress 
          percent={progress} 
          size="small" 
          status={record.status === 'failed' ? 'exception' : record.status === 'completed' ? 'success' : 'active'}
        />
      ),
    },
    { 
      title: 'Created At', 
      dataIndex: 'created_at', 
      key: 'created_at',
      width: 180,
      render: (date: string) => formatDateTime(date),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 150,
      render: (_: unknown, record: ScanTask) => (
        <Space>
          <Tooltip title="View Details">
            <Button 
              size="small" 
              icon={<EyeOutlined />}
              onClick={() => handleViewTask(record)}
            />
          </Tooltip>
          <Popconfirm
            title="Delete Task"
            description="Are you sure you want to delete this task?"
            onConfirm={() => handleDeleteTask(record.id)}
            okText="Yes"
            cancelText="No"
            disabled={record.status === 'running'}
          >
            <Tooltip title={record.status === 'running' ? 'Cannot delete running task' : 'Delete'}>
              <Button 
                size="small" 
                danger 
                icon={<DeleteOutlined />}
                loading={deleting === record.id}
                disabled={record.status === 'running'}
              />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  // Upload props
  const uploadProps = {
    beforeUpload: (file: File) => {
      const isImage = file.type.startsWith('image/');
      if (!isImage) {
        message.error('You can only upload image files!');
        return Upload.LIST_IGNORE;
      }
      const isLt5M = file.size / 1024 / 1024 < 5;
      if (!isLt5M) {
        message.error('Image must be smaller than 5MB!');
        return Upload.LIST_IGNORE;
      }
      return false; // Prevent auto upload
    },
    fileList,
    onChange: ({ fileList: newFileList }: { fileList: UploadFile[] }) => {
      setFileList(newFileList.slice(-1)); // Only keep the last file
    },
    maxCount: 1,
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
        <Title level={2} style={{ margin: 0 }}>Tasks</Title>
        <Space>
          <Select
            placeholder="Filter by status"
            allowClear
            style={{ width: 150 }}
            value={statusFilter}
            onChange={handleStatusFilterChange}
          >
            <Option value="pending">Pending</Option>
            <Option value="running">Running</Option>
            <Option value="completed">Completed</Option>
            <Option value="failed">Failed</Option>
          </Select>
          <Button 
            icon={<ReloadOutlined />} 
            onClick={fetchTasks}
            loading={loading}
          >
            Refresh
          </Button>
          <Button 
            type="primary" 
            icon={<PlusOutlined />}
            onClick={handleOpenCreateModal}
          >
            Create Task
          </Button>
        </Space>
      </div>
      
      <Table 
        columns={columns} 
        dataSource={tasks} 
        rowKey="id"
        loading={loading}
        pagination={{
          current: pagination.page,
          pageSize: pagination.pageSize,
          total: pagination.total,
          showSizeChanger: true,
          showQuickJumper: false,
          pageSizeOptions: ['10', '20', '50', '100'],
          showTotal: (total: number) => `Total ${total} tasks`,
        }}
        onChange={handleTableChange}
      />

      {/* Create Task Modal */}
      <Modal
        title={
          <Space>
            <CloudServerOutlined />
            <span>Create Scan Task</span>
          </Space>
        }
        open={createModalVisible}
        onCancel={() => setCreateModalVisible(false)}
        footer={null}
        width={700}
        destroyOnClose
      >
        <Form
          form={form}
          layout="vertical"
          onFinish={handleCreateTask}
        >
          <Form.Item
            name="name"
            label="Task Name"
            rules={[{ required: true, message: 'Please enter task name' }]}
          >
            <Input placeholder="Enter task name" />
          </Form.Item>

          <Form.Item
            name="credentialIds"
            label="AWS Accounts"
            rules={[{ required: true, message: 'Please select at least one AWS account' }]}
          >
            <Select
              mode="multiple"
              placeholder="Select AWS accounts"
              loading={credentialsLoading}
              optionFilterProp="children"
            >
              {credentials.map((cred: AWSCredential) => (
                <Option key={cred.id} value={cred.id}>
                  {cred.name} ({cred.account_id})
                </Option>
              ))}
            </Select>
          </Form.Item>

          <Form.Item
            name="regions"
            label="AWS Regions"
            rules={[{ required: true, message: 'Please select at least one region' }]}
          >
            <Select
              mode="multiple"
              placeholder="Select AWS regions"
              optionFilterProp="children"
            >
              {AWS_REGIONS.map(region => (
                <Option key={region.value} value={region.value}>
                  {region.label} ({region.value})
                </Option>
              ))}
            </Select>
          </Form.Item>

          <Title level={5}>Project Metadata</Title>

          <Form.Item
            name="clientName"
            label="Client Name"
            rules={[
              { required: true, message: 'Please enter client name' },
              { 
                pattern: /^[^<>\/\\|*:?"]*$/, 
                message: 'Cannot contain < > / \\ | * : ? "' 
              }
            ]}
          >
            <Input placeholder="Enter client name" />
          </Form.Item>

          <Form.Item
            name="projectName"
            label="Project Name"
            rules={[
              { required: true, message: 'Please enter project name' },
              { 
                pattern: /^[^<>\/\\|*:?"]*$/, 
                message: 'Cannot contain < > / \\ | * : ? "' 
              }
            ]}
          >
            <Input placeholder="Enter project name" />
          </Form.Item>

          <Form.Item
            name="bdManager"
            label="BD Manager Name"
          >
            <Input placeholder="Enter BD Manager name" />
          </Form.Item>

          <Form.Item
            name="bdManagerEmail"
            label="BD Manager Email"
            rules={[{ type: 'email', message: 'Please enter a valid email' }]}
          >
            <Input placeholder="Enter BD Manager email" />
          </Form.Item>

          <Form.Item
            name="solutionsArchitect"
            label="Solutions Architect Name"
          >
            <Input placeholder="Enter Solutions Architect name" />
          </Form.Item>

          <Form.Item
            name="solutionsArchitectEmail"
            label="Solutions Architect Email"
            rules={[{ type: 'email', message: 'Please enter a valid email' }]}
          >
            <Input placeholder="Enter Solutions Architect email" />
          </Form.Item>

          <Form.Item
            name="cloudEngineer"
            label="Cloud Engineer Name"
          >
            <Input placeholder="Enter Cloud Engineer name" />
          </Form.Item>

          <Form.Item
            name="cloudEngineerEmail"
            label="Cloud Engineer Email"
            rules={[{ type: 'email', message: 'Please enter a valid email' }]}
          >
            <Input placeholder="Enter Cloud Engineer email" />
          </Form.Item>

          <Form.Item
            name="networkDiagram"
            label="Network Diagram"
          >
            <Upload {...uploadProps} listType="picture">
              <Button icon={<UploadOutlined />}>Upload Network Diagram</Button>
            </Upload>
          </Form.Item>

          <Form.Item style={{ marginBottom: 0, textAlign: 'right' }}>
            <Space>
              <Button onClick={() => setCreateModalVisible(false)}>
                Cancel
              </Button>
              <Button type="primary" htmlType="submit" loading={creating}>
                Create Task
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Modal>

      {/* Task Detail Modal */}
      <Modal
        title={
          <Space>
            <EyeOutlined />
            <span>Task Details</span>
          </Space>
        }
        open={detailModalVisible}
        onCancel={() => {
          setDetailModalVisible(false);
          setSelectedTask(null);
          setTaskLogs([]);
        }}
        footer={
          <Button onClick={() => setDetailModalVisible(false)}>
            Close
          </Button>
        }
        width={800}
      >
        {selectedTask && (
          <div>
            <Card size="small" style={{ marginBottom: 16 }}>
              <Descriptions column={2} size="small">
                <Descriptions.Item label="Task ID">{selectedTask.id}</Descriptions.Item>
                <Descriptions.Item label="Name">{selectedTask.name}</Descriptions.Item>
                <Descriptions.Item label="Status">
                  <Tag color={statusColors[selectedTask.status]} icon={statusIcons[selectedTask.status]}>
                    {selectedTask.status.toUpperCase()}
                  </Tag>
                </Descriptions.Item>
                <Descriptions.Item label="Progress">
                  <Progress 
                    percent={selectedTask.progress} 
                    size="small" 
                    style={{ width: 150 }}
                    status={selectedTask.status === 'failed' ? 'exception' : selectedTask.status === 'completed' ? 'success' : 'active'}
                  />
                </Descriptions.Item>
                <Descriptions.Item label="Created At">{formatDateTime(selectedTask.created_at)}</Descriptions.Item>
                <Descriptions.Item label="Completed At">{formatDateTime(selectedTask.completed_at)}</Descriptions.Item>
                <Descriptions.Item label="Regions" span={2}>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: '4px' }}>
                    {selectedTask.regions?.map((r: string) => <Tag key={r}>{r}</Tag>) || '-'}
                  </div>
                </Descriptions.Item>
              </Descriptions>
            </Card>

            {selectedTask.project_metadata && (
              <Card title="Project Metadata" size="small" style={{ marginBottom: 16 }}>
                <Descriptions column={2} size="small">
                  <Descriptions.Item label="Client Name">
                    {selectedTask.project_metadata.clientName || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Project Name">
                    {selectedTask.project_metadata.projectName || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="BD Manager Name">
                    {selectedTask.project_metadata.bdManager || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="BD Manager Email">
                    {selectedTask.project_metadata.bdManagerEmail || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Solutions Architect Name">
                    {selectedTask.project_metadata.solutionsArchitect || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Solutions Architect Email">
                    {selectedTask.project_metadata.solutionsArchitectEmail || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Cloud Engineer Name">
                    {selectedTask.project_metadata.cloudEngineer || '-'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Cloud Engineer Email">
                    {selectedTask.project_metadata.cloudEngineerEmail || '-'}
                  </Descriptions.Item>
                </Descriptions>
              </Card>
            )}

            <Card 
              title={
                <Space>
                  <ExclamationCircleOutlined />
                  <span>Task Logs</span>
                </Space>
              } 
              size="small"
            >
              {logsLoading ? (
                <div style={{ textAlign: 'center', padding: 20 }}>
                  <Spin />
                </div>
              ) : taskLogs.length === 0 ? (
                <Alert message="No logs available" type="info" showIcon />
              ) : (
                <List
                  size="small"
                  dataSource={taskLogs}
                  renderItem={(log: ErrorLog) => (
                    <List.Item>
                      <List.Item.Meta
                        avatar={
                          <Tag color={log.level === 'error' ? 'red' : log.level === 'warning' ? 'orange' : 'blue'}>
                            {log.level.toUpperCase()}
                          </Tag>
                        }
                        title={log.message}
                        description={
                          <Space direction="vertical" size={0}>
                            <Text type="secondary" style={{ fontSize: 12 }}>
                              {formatDateTime(log.created_at)}
                            </Text>
                            {log.details && (
                              <Text type="secondary" style={{ fontSize: 12 }}>
                                {typeof log.details === 'string' ? log.details : JSON.stringify(log.details)}
                              </Text>
                            )}
                          </Space>
                        }
                      />
                    </List.Item>
                  )}
                  style={{ maxHeight: 300, overflow: 'auto' }}
                />
              )}
            </Card>
          </div>
        )}
      </Modal>
    </div>
  );
}
