import { useState, useEffect, useMemo, useCallback, CSSProperties } from 'react';
import {
  Layout,
  Row,
  Col,
  Card,
  Statistic,
  Button,
  Space,
  Table,
  List,
  Input,
  Badge,
  Dropdown,
  Typography,
  message,
  Modal,
  Grid,
  Avatar,
  Tag
} from 'antd';
import {
  DashboardOutlined,
  TeamOutlined,
  CalendarOutlined,
  MedicineBoxOutlined,
  DollarOutlined,
  UserAddOutlined,
  FileTextOutlined,
  BellOutlined,
  UserOutlined,
  SettingOutlined,
  LogoutOutlined,
  ExperimentOutlined
} from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { PatientsService } from '@/services/patients';
import { AppointmentsService } from '@/services/appointments';
import { DepartmentsService } from '@/services/departments';
import { ClinicalService } from '@/services/clinical';
import { BillingService } from '@/services/billing';
import { ROUTES } from '@/constants/routes';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';

const { Header, Content } = Layout;
const { Title, Text } = Typography;
const { Search } = Input;
const { useBreakpoint } = Grid;

interface Patient {
  id: string;
  patient_number: string;
  first_name: string;
  last_name: string;
  date_of_birth: string;
  gender: string;
  phone?: string;
  email?: string;
  created_at: string;
}

interface Appointment {
  id: string;
  patient_id: string;
  doctor_id: string;
  department_id?: string;
  appointment_date: string;
  appointment_time: string;
  duration_minutes: number;
  appointment_type: string;
  status: string;
  reason?: string;
  notes?: string;
}

interface Department {
  id: string;
  name: string;
  description?: string;
}

interface Invoice {
  id: string;
  invoice_number: string;
  total_amount: number;
  amount_paid: number;
  status: string;
  invoice_date: string;
}

interface LabTest {
  id: string;
  patient_id: string;
  test_name: string;
  status: string;
  ordered_date: string;
}

interface PaginatedResponse<T> {
  items: T[];
  total: number;
  limit: number;
  offset: number;
}

interface StatusBadgeProps {
  status: string;
}

const StatusBadge = ({ status }: StatusBadgeProps) => {
  const statusConfig: Record<string, { color: string; text: string }> = {
    SCHEDULED: { color: 'blue', text: 'Scheduled' },
    CONFIRMED: { color: 'cyan', text: 'Confirmed' },
    CHECKED_IN: { color: 'green', text: 'Checked In' },
    IN_PROGRESS: { color: 'orange', text: 'In Progress' },
    COMPLETED: { color: 'default', text: 'Completed' },
    CANCELLED: { color: 'red', text: 'Cancelled' },
    NO_SHOW: { color: 'volcano', text: 'No Show' }
  };

  const config = statusConfig[status] ?? { color: 'default', text: status };
  return <Tag color={config.color}>{config.text}</Tag>;
};

const DashboardPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const screens = useBreakpoint();
  const { notifications } = useAppContext();

  const [searchQuery, setSearchQuery] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(true);
  const [todayRevenue, setTodayRevenue] = useState<number>(0);

  const todayDate = useMemo(() => {
    const date = new Date();
    return date.toISOString().split('T')[0];
  }, []);

  const {
    data: recentPatientsData,
    loading: recentPatientsLoading,
    execute: fetchRecentPatients
  } = useApi<PaginatedResponse<Patient>>(PatientsService.list);

  const {
    data: totalPatientsData,
    execute: fetchTotalPatients
  } = useApi<PaginatedResponse<Patient>>(PatientsService.list);

  const {
    data: todayAppointmentsData,
    loading: todayAppointmentsLoading,
    execute: fetchTodayAppointments
  } = useApi<PaginatedResponse<Appointment>>(AppointmentsService.list);

  const {
    data: pendingCheckinsData,
    loading: pendingCheckinsLoading,
    execute: fetchPendingCheckins
  } = useApi<PaginatedResponse<Appointment>>(AppointmentsService.list);

  const {
    data: departmentsData,
    execute: fetchDepartments
  } = useApi<PaginatedResponse<Department>>(DepartmentsService.list);

  const {
    data: consultationsData,
    execute: fetchConsultations
  } = useApi<PaginatedResponse<{ id: string }>>(ClinicalService.getConsultations);

  const {
    data: invoicesData,
    execute: fetchInvoices
  } = useApi<PaginatedResponse<Invoice>>(BillingService.getInvoices);

  const {
    data: pendingLabTestsData,
    execute: fetchPendingLabTests
  } = useApi<PaginatedResponse<LabTest>>(ClinicalService.getLabTests);

  const {
    data: searchResultsData,
    execute: executeSearch
  } = useApi<PaginatedResponse<Patient>>(PatientsService.list);

  const recentPatients = useMemo(() => recentPatientsData?.items ?? [], [recentPatientsData]);
  const todayAppointments = useMemo(() => todayAppointmentsData?.items ?? [], [todayAppointmentsData]);
  const pendingCheckins = useMemo(() => pendingCheckinsData?.items ?? [], [pendingCheckinsData]);
  const pendingLabTests = useMemo(() => pendingLabTestsData?.items ?? [], [pendingLabTestsData]);

  const totalPatientsCount = useMemo(() => totalPatientsData?.total ?? 0, [totalPatientsData]);
  const todayAppointmentsCount = useMemo(() => todayAppointments.length, [todayAppointments]);
  const todayConsultationsCount = useMemo(() => consultationsData?.total ?? 0, [consultationsData]);

  const unreadNotificationsCount = useMemo(
    () => (notifications ?? []).filter((n: { read: boolean }) => !n.read).length,
    [notifications]
  );

  useEffect(() => {
    const loadDashboard = async () => {
      setLoading(true);
      try {
        await Promise.all([
          fetchRecentPatients({ limit: 5, offset: 0 }),
          fetchTotalPatients({ limit: 1, offset: 0 }),
          fetchTodayAppointments({ limit: 50, offset: 0, appointment_date: todayDate }),
          fetchPendingCheckins({ limit: 20, offset: 0, status: 'SCHEDULED', appointment_date: todayDate }),
          fetchDepartments({ limit: 50, offset: 0 }),
          fetchConsultations({ limit: 1, offset: 0 }),
          fetchInvoices({ limit: 50, offset: 0 }),
          fetchPendingLabTests({ limit: 10, offset: 0, status: 'ORDERED' })
        ]);
      } catch (e) {
        const { message: errorMsg } = parseError(e);
        messageApi.error(errorMsg);
      } finally {
        setLoading(false);
      }
    };

    void loadDashboard();
  }, [
    fetchRecentPatients,
    fetchTotalPatients,
    fetchTodayAppointments,
    fetchPendingCheckins,
    fetchDepartments,
    fetchConsultations,
    fetchInvoices,
    fetchPendingLabTests,
    todayDate,
    messageApi
  ]);

  useEffect(() => {
    if (invoicesData?.items) {
      const revenue = invoicesData.items.reduce((sum, inv) => {
        const invDate = inv.invoice_date;
        if (invDate === todayDate) {
          return sum + (Number(inv.amount_paid) || 0);
        }
        return sum;
      }, 0);
      setTodayRevenue(revenue);
    }
  }, [invoicesData, todayDate]);

  const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchQuery(e.target.value);
  }, []);

  const handleSearch = useCallback(async () => {
    if (!searchQuery.trim()) return;
    try {
      await executeSearch({ limit: 10, offset: 0, search: searchQuery });
    } catch (e) {
      const { message: errorMsg } = parseError(e);
      messageApi.error(errorMsg);
    }
  }, [searchQuery, executeSearch, messageApi]);

  const handleCheckIn = useCallback(
    async (appointmentId: string) => {
      Modal.confirm({
        title: 'Check In Patient',
        content: 'Confirm check-in for this appointment?',
        onOk: async () => {
          try {
            await AppointmentsService.createCheckIn(appointmentId);
            messageApi.success('Patient checked in successfully!');
            await fetchPendingCheckins({ limit: 20, offset: 0, status: 'SCHEDULED', appointment_date: todayDate });
            await fetchTodayAppointments({ limit: 50, offset: 0, appointment_date: todayDate });
          } catch (e) {
            const { message: errorMsg } = parseError(e);
            messageApi.error(errorMsg);
          }
        }
      });
    },
    [fetchPendingCheckins, fetchTodayAppointments, todayDate, messageApi]
  );

  const handleQuickRegisterPatient = useCallback(() => {
    navigate(ROUTES.PATIENTS);
  }, [navigate]);

  const handleQuickNewAppointment = useCallback(() => {
    navigate(ROUTES.APPOINTMENTS);
  }, [navigate]);

  const handleQuickNewConsultation = useCallback(() => {
    navigate(ROUTES.CLINICAL);
  }, [navigate]);

  const handleMenuClick = useCallback(
    ({ key }: { key: string }) => {
      if (key === 'logout') {
        navigate(ROUTES.LOGIN);
      }
    },
    [navigate]
  );

  const userMenuItems = useMemo(
    () => [
      { key: 'profile', label: 'My Profile', icon: <UserOutlined /> },
      { key: 'settings', label: 'Settings', icon: <SettingOutlined /> },
      { type: 'divider' as const },
      { key: 'logout', label: 'Logout', icon: <LogoutOutlined />, danger: true }
    ],
    []
  );

  const appointmentsColumns = useMemo(
    () => [
      {
        title: 'Patient',
        dataIndex: 'patient_id',
        key: 'patient_id',
        render: (id: string) => <Text>{id}</Text>
      },
      {
        title: 'Doctor',
        dataIndex: 'doctor_id',
        key: 'doctor_id',
        render: (id: string) => <Text>{id}</Text>
      },
      {
        title: 'Department',
        dataIndex: 'department_id',
        key: 'department_id',
        render: (id?: string) => <Text>{id ?? '—'}</Text>,
        responsive: ['md' as const]
      },
      {
        title: 'Time',
        dataIndex: 'appointment_time',
        key: 'appointment_time'
      },
      {
        title: 'Type',
        dataIndex: 'appointment_type',
        key: 'appointment_type',
        render: (type: string) => <Tag>{type}</Tag>,
        responsive: ['lg' as const]
      },
      {
        title: 'Status',
        dataIndex: 'status',
        key: 'status',
        render: (status: string) => <StatusBadge status={status} />
      }
    ],
    []
  );

  const padding = useMemo<number>(() => (screens.xs ? 12 : 24), [screens.xs]);

  return (
    <div style={{ padding, minHeight: '100%', background: '#f5f5f5' }}>
      {contextHolder}

      <div style={{ marginBottom: 24, display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 16 }}>
        <Title level={screens.xs ? 4 : 3} style={{ margin: 0 }}>
          Dashboard
        </Title>
        <Space size="middle" wrap>
          <Search
            placeholder="Search patients by name, ID, or phone..."
            allowClear
            value={searchQuery}
            onChange={handleSearchChange}
            onSearch={handleSearch}
            style={{ width: screens.xs ? '100%' : 360 }}
          />
          <Badge count={unreadNotificationsCount} size="small">
            <Button type="text" icon={<BellOutlined />} shape="circle" />
          </Badge>
          <Dropdown menu={{ items: userMenuItems, onClick: handleMenuClick }} trigger={['click']}>
            <Button type="text" icon={<UserOutlined />} />
          </Dropdown>
        </Space>
      </div>

      <Row gutter={[16, 16]}>
        <Col xs={24} sm={12} lg={6}>
          <Card hoverable size="small" style={{ borderLeft: '4px solid #1677ff' }}>
            <Statistic
              title="Total Patients"
              value={totalPatientsCount}
              prefix={<TeamOutlined />}
              valueStyle={{ color: '#1677ff' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={12} lg={6}>
          <Card hoverable size="small" style={{ borderLeft: '4px solid #52c41a' }}>
            <Statistic
              title="Today's Appointments"
              value={todayAppointmentsCount}
              prefix={<CalendarOutlined />}
              valueStyle={{ color: '#52c41a' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={12} lg={6}>
          <Card hoverable size="small" style={{ borderLeft: '4px solid #fa8c16' }}>
            <Statistic
              title="Today's Consultations"
              value={todayConsultationsCount}
              prefix={<MedicineBoxOutlined />}
              valueStyle={{ color: '#fa8c16' }}
            />
          </Card>
        </Col>
        <Col xs={24} sm={12} lg={6}>
          <Card hoverable size="small" style={{ borderLeft: '4px solid #722ed1' }}>
            <Statistic
              title="Today's Revenue"
              value={todayRevenue}
              prefix="$"
              precision={2}
              valueStyle={{ color: '#722ed1' }}
            />
          </Card>
        </Col>
      </Row>

      <Row gutter={[16, 16]} style={{ marginTop: 16 }}>
        <Col span={24}>
          <Card title="Quick Actions" size="small">
            <Space size="middle" wrap>
              <Button type="primary" icon={<UserAddOutlined />} onClick={handleQuickRegisterPatient}>
                Register Patient
              </Button>
              <Button type="primary" ghost icon={<CalendarOutlined />} onClick={handleQuickNewAppointment}>
                New Appointment
              </Button>
              <Button type="primary" ghost icon={<FileTextOutlined />} onClick={handleQuickNewConsultation}>
                New Consultation
              </Button>
            </Space>
          </Card>
        </Col>
      </Row>

      <Row gutter={[16, 16]} style={{ marginTop: 16 }}>
        <Col xs={24} lg={16}>
          <Card
            title="Today's Appointments"
            size="small"
            extra={
              <Button type="link" onClick={() => navigate(ROUTES.APPOINTMENTS)}>
                View All
              </Button>
            }
          >
            <Table
              dataSource={todayAppointments}
              columns={appointmentsColumns}
              rowKey="id"
              loading={todayAppointmentsLoading}
              pagination={{ pageSize: 8, showSizeChanger: false }}
              size={screens.xs ? 'small' : 'middle'}
              scroll={{ x: 'max-content' }}
            />
          </Card>
        </Col>

        <Col xs={24} lg={8}>
          <Card title="Pending Check-ins" size="small">
            <List
              dataSource={pendingCheckins}
              loading={pendingCheckinsLoading}
              size="small"
              renderItem={(item: Appointment) => (
                <List.Item
                  actions={[
                    <Button key="checkin" type="link" size="small" onClick={() => handleCheckIn(item.id)}>
                      Check In
                    </Button>
                  ]}
                >
                  <List.Item.Meta title={item.patient_id} description={item.appointment_time} />
                </List.Item>
              )}
            />
          </Card>

          {!screens.xs && (
            <Card title="Recent Registrations" size="small" style={{ marginTop: 16 }}>
              <List
                dataSource={recentPatients}
                loading={recentPatientsLoading}
                size="small"
                renderItem={(item: Patient) => (
                  <List.Item>
                    <List.Item.Meta
                      avatar={<Avatar icon={<UserOutlined />} />}
                      title={`${item.first_name} ${item.last_name}`}
                      description={item.patient_number}
                    />
                  </List.Item>
                )}
              />
            </Card>
          )}

          <Card title="System Alerts" size="small" style={{ marginTop: 16 }}>
            <List
              dataSource={pendingLabTests}
              size="small"
              renderItem={(item: LabTest) => (
                <List.Item>
                  <List.Item.Meta
                    avatar={<ExperimentOutlined />}
                    title={item.test_name}
                    description={`Status: ${item.status}`}
                  />
                </List.Item>
              )}
            />
          </Card>
        </Col>
      </Row>
    </div>
  );
};

export default DashboardPage;