"use client";

import React, { useEffect, useState, useCallback } from "react";
import { Container, Row, Col, Card, ListGroup, Form, FloatingLabel, Badge, Button, Stack, Spinner } from "react-bootstrap";
import { useForm, Controller } from "react-hook-form";
import { useToast } from "@/context/ToastContext";
import LoadingCMS from "@/components/LoadingCMS";
import { unixToDateTime, findValue } from "@/lib/function";

type FormData = {
  su_id: number;
  su_ut_id: number;
  su_name: string;
  su_email: string;
  su_mobile: string;  
  su_password: string;
  su_status: number;
  su_date: number;
  lastLogin: number;
};
type TypeData = {
  ut_id: number;
  ut_name: string;
};
export default function Users() {
  const { showToast } = useToast();
  const [users, setUsers] = useState<FormData[]>([]);
  const [userType, setUserType] = useState<TypeData[]>([]);
  const [isLoading, setLoading] = useState(true);
  const [selectedUser, setSelectedUser] = useState<FormData | null>(null);
  const [search, setSearch] = useState("");
  const [selectedType, setSelectedType] = useState<number | "">("");
  const { register, handleSubmit, reset, control, formState: { errors, isSubmitting } } = useForm<FormData>({
    defaultValues: {
      su_id: 0,
      su_ut_id: 0,
      su_name: "",
      su_email: "",
      su_mobile: "",
      su_status: 0,
      su_password: "",
    }
  });
  const fetchAllUser = useCallback(async (utId?: number) => {
    try {
      const res = await fetch("/api/user/list", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ utId })
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.data)) {
        setUsers(json.data);
      }
    } catch {
      showToast("User List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);
  const fetchBlogType = useCallback(async () => {
    try {
      const res = await fetch("/api/user/type");
      const json = await res.json();
      if (res.ok && Array.isArray(json.data)) {
        setUserType(json.data);
      }
    } catch {
      showToast("User Type: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);
  useEffect(() => {
    fetchAllUser();
    fetchBlogType();
  }, [fetchAllUser,fetchBlogType]);
  useEffect(() => {
    if (selectedUser) {
      reset({
        ...selectedUser,
        su_status: selectedUser.su_status ? 1 : 0,
        su_password: "",
      });
    }
  }, [selectedUser, reset]);
  const filteredUsers = users.filter((user) => {
    const matchesSearch =
      user.su_name?.toLowerCase().includes(search.toLowerCase()) ||
      user.su_mobile?.toLowerCase().includes(search.toLowerCase());

    const matchesType = selectedType === "" || user.su_ut_id === selectedType;
    return matchesSearch && matchesType;
  });
  const onSubmit = async (data: FormData) => {
    try {      
      const res = await fetch("/api/user/update", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
            id: data.su_id,            
            callBy: "admin",
            callMode: "all",
            ...data,
        }),
      });
      const result = await res.json();
      if (res.ok) {
        showToast(result.message, "success");
        reset({
          su_id: 0,
          su_ut_id: 0,
          su_name: "",
          su_email: "",
          su_mobile: "",
          su_status: 0,
          su_password: "",
        });        
        setSelectedUser(null);
        fetchAllUser();
      } else {
        showToast(result.error, "danger");
      }
    } catch {
      showToast("User Update: Failed to update.", "danger");
    }
  };
  if (isLoading) return <LoadingCMS />;
  return (
    <Container fluid className="py-3">
      <Row>        
        <Col md={8}>
          <Row xs={1} md={2} className="g-3">
            <Col md={3}>
              <h1 className="fs-3">Users <small className="text-body-secondary">({filteredUsers.length})</small></h1>
            </Col>
            <Col md={6}>
              <FloatingLabel label="Search by name, mobile or email">
                <Form.Control value={search} onChange={(e) => setSearch(e.target.value)} />
              </FloatingLabel>
            </Col>
            <Col md={3}>
              <FloatingLabel label="User Type">
                <Form.Select value={selectedType} onChange={(e) => setSelectedType(e.target.value === "" ? "" : Number(e.target.value))}>
                  <option value="">All</option>
                  {userType.map((type) => (
                    <option key={type.ut_id} value={type.ut_id}>
                      {type.ut_name}
                    </option>
                  ))}
                </Form.Select>
              </FloatingLabel>
            </Col>
            {filteredUsers.map((user, index) => (
              <Col key={index}>
                <Card className={`h-100 rounded-4 ${selectedUser && selectedUser.su_id === user.su_id ? 'text-bg-success' : null}`}>
                  <Card.Body>
                    <Card.Title className="d-flex align-items-start m-0">
                      <span className="flex-fill me-3">{user.su_name}</span>
                      {user.su_status === 1 ? <Badge bg="primary">Active</Badge> : <Badge bg="secondary">Inactive</Badge>}
                    </Card.Title>                    
                  </Card.Body>
                  <ListGroup variant="flush">
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Email <span className="ms-3">{user.su_email}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Mobile <span className="ms-3">{user.su_mobile}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Type <span className="ms-3">{findValue(userType,"ut_id",user.su_ut_id,"ut_name","Unknown")}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Join Date <span className="ms-3">{unixToDateTime(user.su_date,'date')}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Last Login <span className="ms-3">{unixToDateTime(user.lastLogin)}</span>
                    </ListGroup.Item>
                  </ListGroup>
                  <Card.Footer>
                    <Button variant="outline-danger" className="w-100 rounded-pill" onClick={() => setSelectedUser(user)}>
                      Edit
                    </Button>
                  </Card.Footer>
                </Card>
              </Col>
            ))}
          </Row>
        </Col>
        <Col md={4} className="position-sticky vh-100 overflow-y-auto" style={{ top: "1rem"}}>
          <Card className="rounded-4 bg-light">
            <Card.Body>
              <h4 className="mb-4">Edit User</h4>
              <Form noValidate onSubmit={handleSubmit(onSubmit)}>
                <Row className="g-3">
                  <Col md={12}>
                    <FloatingLabel label="Type">
                      <Form.Select {...register("su_ut_id", { required: "User Type is required", valueAsNumber: true, validate: (value) => value > 0 || "Please select a valid User Type" })} isInvalid={!!errors.su_ut_id} >
                        <option value="0">Please Select</option>
                        {userType.map((type) => (
                          <option key={type.ut_id} value={type.ut_id}>
                            {type.ut_name}
                          </option>
                        ))}
                      </Form.Select>
                      <Form.Control.Feedback type="invalid">{errors.su_ut_id?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Name">
                      <Form.Control type="text" {...register("su_name", { required: "Full name is required", pattern: { value: /^[a-zA-Z]+ [a-zA-Z]+$/, message: "Enter first and last name", }, })} isInvalid={!!errors.su_name} />
                      <Form.Control.Feedback type="invalid">{errors.su_name?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Email">
                      <Form.Control type="email" {...register("su_email", { required: "Email is required", pattern: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "Invalid email format", }, })} isInvalid={!!errors.su_email} />
                      <Form.Control.Feedback type="invalid">{errors.su_email?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Mobile">
                      <Form.Control type="tel" {...register("su_mobile", { required: "Mobile number is required", pattern: { value: /^[6-9]\d{9}$/, message: "Enter a valid 10-digit Indian mobile number", }, })} isInvalid={!!errors.su_mobile} />
                      <Form.Control.Feedback type="invalid">{errors.su_mobile?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <FloatingLabel label="Password">
                      <Form.Control type="password" {...register("su_password", { pattern: { value: /^(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*]).{8,}$/, message: "Min 8 chars, 1 uppercase, 1 number, 1 special", }, })} isInvalid={!!errors.su_password} />
                      <Form.Control.Feedback type="invalid">{errors.su_password?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <Controller name="su_status" control={control} defaultValue={0} render={({ field }) => (
                      <Form.Check type="switch" id="su_status" label="User Status" checked={field.value === 1} onChange={(e) => field.onChange(e.target.checked ? 1 : 0)} />
                      )}
                    />
                  </Col>
                  {selectedUser &&                 
                  <Col md={12}>
                    <Stack direction="horizontal" gap={3}>
                      <Button type="submit" variant="danger" className="w-100 rounded-pill" disabled={isSubmitting}>
                        {isSubmitting ? (
                          <Stack gap={2} direction="horizontal">
                            <Spinner animation="grow" size="sm" variant="danger" />
                            <Spinner animation="grow" size="sm" variant="primary" />
                            <Spinner animation="grow" size="sm" variant="success" />
                            <span>Updating...</span>
                          </Stack>
                        ) : "Update User"}
                      </Button>
                      <Button variant="outline-secondary" className="w-100 rounded-pill" onClick={() => { reset({su_id:0,su_ut_id:0,su_name:"",su_email:"",su_mobile:"",su_status:0,su_password:""}); setSelectedUser(null);}}>Cancel Edit</Button>
                    </Stack>
                  </Col>}
                </Row>
              </Form>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  );
}
